From mstrauss at openjdk.org Sat Apr 1 03:25:28 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 1 Apr 2023 03:25:28 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v2] In-Reply-To: References: Message-ID: <4aMQsZoBgxyshZrr3SpXW2dsgYViXrmXciRnaDt0vns=.10d4b27a-3d5d-45cc-9f4d-7b520fcdeb60@github.com> > `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. > > 1. `removeAll(c)`: > This is a no-op if 'c' is empty. > For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. > > 2. `retainAll(c)`: > This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. > > I've added some tests to verify the optimized behavior for each of the three classes. Michael Strau? has updated the pull request incrementally with two additional commits since the last revision: - address review comments - refactored removeAll/retainAll optimizations ------------- Changes: - all: https://git.openjdk.org/jfx/pull/751/files - new: https://git.openjdk.org/jfx/pull/751/files/af84b648..9a0e29a4 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=751&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=751&range=00-01 Stats: 679 lines in 11 files changed: 573 ins; 72 del; 34 mod Patch: https://git.openjdk.org/jfx/pull/751.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/751/head:pull/751 PR: https://git.openjdk.org/jfx/pull/751 From mstrauss at openjdk.org Sat Apr 1 03:32:43 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 1 Apr 2023 03:32:43 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v3] In-Reply-To: References: Message-ID: > `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. > > 1. `removeAll(c)`: > This is a no-op if 'c' is empty. > For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. > > 2. `retainAll(c)`: > This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. > > I've added some tests to verify the optimized behavior for each of the three classes. Michael Strau? has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains five commits: - Merge branch 'master' into fixes/JDK-8283063 # Conflicts: # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableListWrapper.java # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableMapWrapper.java # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSequentialListWrapper.java # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSetWrapper.java - address review comments - refactored removeAll/retainAll optimizations - Optimize removeAll/retainAll for Observable{List/Set/Map}Wrapper - Failing test ------------- Changes: https://git.openjdk.org/jfx/pull/751/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=751&range=02 Stats: 822 lines in 11 files changed: 799 ins; 8 del; 15 mod Patch: https://git.openjdk.org/jfx/pull/751.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/751/head:pull/751 PR: https://git.openjdk.org/jfx/pull/751 From mstrauss at openjdk.org Sat Apr 1 03:36:27 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 1 Apr 2023 03:36:27 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v2] In-Reply-To: <4aMQsZoBgxyshZrr3SpXW2dsgYViXrmXciRnaDt0vns=.10d4b27a-3d5d-45cc-9f4d-7b520fcdeb60@github.com> References: <4aMQsZoBgxyshZrr3SpXW2dsgYViXrmXciRnaDt0vns=.10d4b27a-3d5d-45cc-9f4d-7b520fcdeb60@github.com> Message-ID: <03BJBIjx92YDH6K7TTvIrfdE56GzHk3clJcV3Rs4XK8=.8353544b-f024-4828-9073-d0ab9b24ed53@github.com> On Sat, 1 Apr 2023 03:25:28 GMT, Michael Strau? wrote: >> `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. >> >> 1. `removeAll(c)`: >> This is a no-op if 'c' is empty. >> For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. >> >> 2. `retainAll(c)`: >> This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. >> >> I've added some tests to verify the optimized behavior for each of the three classes. > > Michael Strau? has updated the pull request incrementally with two additional commits since the last revision: > > - address review comments > - refactored removeAll/retainAll optimizations I've added the suggested optimization for `ModifiableObservableListBase.addAll`, as well as `ObservableSequentialListWrapper.addAll`. Additionally, there are more tests to ensure adherence of the optimized methods to the collection contracts (NPE and IOOBE should be thrown for invalid arguments). ------------- PR Comment: https://git.openjdk.org/jfx/pull/751#issuecomment-1492816029 From mstrauss at openjdk.org Sat Apr 1 03:36:34 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 1 Apr 2023 03:36:34 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v3] In-Reply-To: <_ixCsWPttlgmKoW--42gWJo0lEKTnMAcXqUt2KL19ik=.8a2a17cc-db25-4e38-a549-283a8d8dc4f8@github.com> References: <_ixCsWPttlgmKoW--42gWJo0lEKTnMAcXqUt2KL19ik=.8a2a17cc-db25-4e38-a549-283a8d8dc4f8@github.com> Message-ID: On Thu, 30 Mar 2023 13:03:22 GMT, John Hendrikx wrote: >> Michael Strau? has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains five commits: >> >> - Merge branch 'master' into fixes/JDK-8283063 >> >> # Conflicts: >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableListWrapper.java >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableMapWrapper.java >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSequentialListWrapper.java >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSetWrapper.java >> - address review comments >> - refactored removeAll/retainAll optimizations >> - Optimize removeAll/retainAll for Observable{List/Set/Map}Wrapper >> - Failing test > > modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableListWrapper.java line 172: > >> 170: @Override >> 171: public boolean removeAll(Collection c) { >> 172: if (backingList.isEmpty() || c.isEmpty()) { > > I think you should do an explicit `null` check here on `c` or swap the order of these arguments so it always throws an NPE here if `c` is `null` as per collection contract. If you don't, it will do this implicit `null` check just after `beginChange`, and as I don't see a `try/finally` there to call `endChange`, it would mean the wrapper / changeListBuilder gets in a bad state. I've opted for implicit checks by always dereferencing `c`. > modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableListWrapper.java line 195: > >> 193: @Override >> 194: public boolean retainAll(Collection c) { >> 195: if (backingList.isEmpty()) { > > I think we need to check `c` for `null` here first to conform to the collection contract. Done. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155050099 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155050071 From jhendrikx at openjdk.org Sat Apr 1 08:24:39 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 1 Apr 2023 08:24:39 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v3] In-Reply-To: References: Message-ID: On Sat, 1 Apr 2023 03:32:43 GMT, Michael Strau? wrote: >> `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. >> >> 1. `removeAll(c)`: >> This is a no-op if 'c' is empty. >> For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. >> >> 2. `retainAll(c)`: >> This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. >> >> I've added some tests to verify the optimized behavior for each of the three classes. > > Michael Strau? has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains five commits: > > - Merge branch 'master' into fixes/JDK-8283063 > > # Conflicts: > # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableListWrapper.java > # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableMapWrapper.java > # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSequentialListWrapper.java > # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSetWrapper.java > - address review comments > - refactored removeAll/retainAll optimizations > - Optimize removeAll/retainAll for Observable{List/Set/Map}Wrapper > - Failing test Super happy you also added IOOBE -- collection classes are such a corner stone of Java and the observable variants fulfill that role for JavaFX -- these classes should be really conservative with the inputs they accept as any faulty inputs are likely to be bugs. Programmers have certain expectations when they see `Set`, `List` or `Map`, and expect their inputs to be validated; when those validations are suddenly not working because the implementation happens to be of the `Observable` kind, bugs will go unnoticed. modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableMapWrapper.java line 326: > 324: if (backingMap.isEmpty()) { > 325: return false; > 326: } Passing `null` is always an error, and I think here you still need to throw an NPE first when `c` is `null`, even if the backing map is empty. From `AbstractColection` for example: public boolean retainAll(Collection c) { Objects.requireNonNull(c); ... I realize this was already incorrect, so perhaps out of scope for your PR. modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableMapWrapper.java line 353: > 351: @Override > 352: public boolean removeAll(Collection c) { > 353: if (backingMap.isEmpty() || c.isEmpty()) { This one should also be swapped if you're going for implicit checks. Also I think it really couldn't hurt to add a small comment there (`// implicit null check` for future maintainers -- that's how I see it often done in JDK collection code). modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableMapWrapper.java line 466: > 464: @Override > 465: public boolean removeAll(Collection c) { > 466: if (backingMap.isEmpty() || c.isEmpty()) { This one should also be swapped if you're going for implicit checks. modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableMapWrapper.java line 490: > 488: @Override > 489: public boolean retainAll(Collection c) { > 490: if (backingMap.isEmpty()) { Here the null check is missing, it should be before you check the backingMap as passing `null` is a bug in the caller code. modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSequentialListWrapper.java line 185: > 183: return false; > 184: } > 185: Shouldn't this always check the index? Suggestion: if (index < 0 || index > size()) { throw new IndexOutOfBoundsException("Index: " + index); } if (c.isEmpty()) { // implicit null check return false; } modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSetWrapper.java line 337: > 335: clear(); > 336: return true; > 337: } else if (backingSet.isEmpty()) { minor: style thing that I personally dislike, using an `else` when other branches `throw` or `return` (IDE can flag those) modules/javafx.base/src/main/java/javafx/collections/ModifiableObservableListBase.java line 125: > 123: return false; > 124: } > 125: Shouldn't this always check the index? Suggestion: if (index < 0 || index > size()) { throw new IndexOutOfBoundsException("Index: " + index); } if (c.isEmpty()) { // implicit null check return false; } modules/javafx.base/src/main/java/javafx/collections/ModifiableObservableListBase.java line 142: > 140: > 141: return; > 142: } I'm really happy you also added the index range checks, not only does it conform to the contract better, it will help expose bugs in caller code (or even the JavaFX code as Observable* classes are used in many places, and who knows what bugs might lurk in some of the more complicated classes). I'm not quite sure how this check is suppose to work though; does this need a comment ? Suggestion: if (fromIndex == toIndex) { // distinguish between the clear and remove(int) call if (fromIndex < 0 || fromIndex > size()) { throw new IndexOutOfBoundsException("Index: " + fromIndex); } return; } I think that would be a bit too cryptic for me... modules/javafx.base/src/main/java/javafx/collections/ModifiableObservableListBase.java line 360: > 358: return false; > 359: } > 360: Shouldn't this always check the index, not only when the collection passed in is empty? Otherwise code like: `singleElementSubList.addAll(15, List.of("a"))` would be allowed? Suggestion: if (index < 0 || index > sublist.size()) { throw new IndexOutOfBoundsException("Index: " + index); } if (c.isEmpty()) { // implicit null check return false; } modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableMapWrapperTest.java line 82: > 80: public void testRemoveAllWithNullArgumentThrowsNPE() { > 81: var map = new ObservableMapWrapper<>(new HashMap<>(Map.of("k0", "v0", "k1", "v1", "k2", "v2"))); > 82: assertThrows(NullPointerException.class, () -> map.entrySet().removeAll((Collection) null)); This test fails I think when the map used is empty (no NPE), see other comments. modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableMapWrapperTest.java line 97: > 95: var content = Map.of("k0", "v0", "k1", "v1", "k2", "v2"); > 96: var map = new ObservableMapWrapper<>(new HashMap<>(content)); > 97: assertThrows(NullPointerException.class, () -> map.entrySet().retainAll((Collection) null)); If I'm correct, with an empty map, this would not throw the NPE, see other comments. modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableSequentialListWrapperTest.java line 60: > 58: > 59: @Test > 60: public void testAddAllWithEmptyCollectionArgumentAndInvalidIndexThrowsIOOBE() { How about a variant that doesn't pass an empty collection, `-1` should still fail, and for example `100` should also fail. modules/javafx.base/src/test/java/test/javafx/collections/ModifiableObservableListBaseTest.java line 61: > 59: > 60: @Test > 61: public void testAddAllWithEmptyCollectionArgumentAndInvalidIndexThrowsIOOBE() { Could use variant here I think with a non empty collection, and see if it still throws IOOBE. modules/javafx.base/src/test/java/test/javafx/collections/ModifiableObservableListBaseTest.java line 157: > 155: > 156: @Test > 157: public void testAddAllWithEmptyCollectionArgumentAndInvalidIndexThrowsIOOBE() { Could use variant here with non-empty collection, and see if it still throws IOOBE. ------------- Changes requested by jhendrikx (Committer). PR Review: https://git.openjdk.org/jfx/pull/751#pullrequestreview-1367824444 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155072066 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155072511 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155072566 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155072688 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155076010 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155073032 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155076300 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155074911 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155075825 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155073919 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155073715 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155076496 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155076585 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155076617 From duke at openjdk.org Sat Apr 1 08:57:30 2023 From: duke at openjdk.org (Alessadro Parisi) Date: Sat, 1 Apr 2023 08:57:30 GMT Subject: Withdrawn: 8263095: Provide a way for a custom control to indicate that its userAgentStyleSheet has changed In-Reply-To: <_FO9Rfzh0C5DItqp1cCCCHtayURl4r48IN54Yp9an4c=.ee7648e4-e70a-426e-a1d3-77462d51b544@github.com> References: <_FO9Rfzh0C5DItqp1cCCCHtayURl4r48IN54Yp9an4c=.ee7648e4-e70a-426e-a1d3-77462d51b544@github.com> Message-ID: On Mon, 31 May 2021 13:57:22 GMT, Alessadro Parisi wrote: > This change allows custom control to change their style dynamically > When the user-agent stylesheet changes the property automatically calls `NodeHelper.reapplyCSS(Region.this);` to recompute the CSS for the node and its children. > To make this work the StyleManager class must be fixed too. > The line `regionUserAgentStylesheet = weakRegionUserAgentStylesheetMap.computeIfAbsent((Region)region, Region::getUserAgentStylesheet); > ` is problematic because if the region is already present in the map but the user-agent stylesheet changed, the value of `regionUserAgentStylesheet` is not updated and this leads to controls having the wrong style. > To fix this issue I added this check: > > if (((Region) region).getUserAgentStylesheet() != null && !((Region) region).getUserAgentStylesheet().equals(regionUserAgentStylesheet)) { > weakRegionUserAgentStylesheetMap.put((Region) region, ((Region) region).getUserAgentStylesheet()); > regionUserAgentStylesheet = ((Region) region).getUserAgentStylesheet(); > } This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jfx/pull/525 From jhendrikx at openjdk.org Sat Apr 1 09:08:30 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 1 Apr 2023 09:08:30 GMT Subject: RFR: JDK-8298060: Fix precision bug in gesture recognizer classes [v3] In-Reply-To: <0b71d2ypgR4ww4hlEw5paLEn4JejB50Y4yajKDhIj_A=.429d6126-cbd5-4019-ae63-865b89fe7ddd@github.com> References: <0b71d2ypgR4ww4hlEw5paLEn4JejB50Y4yajKDhIj_A=.429d6126-cbd5-4019-ae63-865b89fe7ddd@github.com> Message-ID: On Thu, 15 Dec 2022 12:23:12 GMT, John Hendrikx wrote: >> This includes a fix for the precision problem we've found as part of the graphics warnings clean ups. >> >> I've included two commits, one with just the minimal fix, and one with the clean ups. I can drop off the 2nd commit if it is deemed to be of no added value. > > John Hendrikx has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains five commits: > > - Merge remote-tracking branch 'upstream/master' into feature/precision-problem-in-gesture-recognizers > - Make RotateGestureRecognizer easier to test > - Revert all changes to RotateGestureRecognizer > - General clean ups > > - Made constants written in capitals final > - Made fields final that can be final > - Made fields and methods private that can be private > - Renamed constants that aren't constant to camel case > - Fixed spelling errors > - Re-ordered fields (statics at the top) > - Removed redundant initial values > - Removed unused fields and parameters > - Optimized imports > - Removed commented out code > - Fix precision problems in gesture recognizers I think this change still has merit. I also think the change to make the code more testable is a good thing. A lot of code in JavaFX is hard to test, and when things are hard to test, the testing is often done poorly or not at all -- these classes did not have any tests. ------------- PR Comment: https://git.openjdk.org/jfx/pull/966#issuecomment-1492885820 From mhanl at openjdk.org Sat Apr 1 09:51:24 2023 From: mhanl at openjdk.org (Marius Hanl) Date: Sat, 1 Apr 2023 09:51:24 GMT Subject: RFR: JDK-8305248: TableView not rendered correctly after column is made visible if fixed cell size is set In-Reply-To: References: Message-ID: On Fri, 31 Mar 2023 08:57:20 GMT, Jose Pereda wrote: >> The determined `prefWidth` of a `TableCell` could be `0.0` when a `fixedCellSize` is set. >> This happened because the `TableCell` may not have a skin since it was never added to the scene graph yet. >> >> The fix is to make sure we get the `prefWidth` after the `TableCell` was added to the scene graph. >> That is also the reason why the problem only happened the first time and never again after (skin is then already created). > > modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/TableRowSkinTest.java line 251: > >> 249: >> 250: /** >> 251: * When we make an invisible column visible we expect the underlying cells to be visible, e.g. as width > 0. > > This only applies to the case of fixed cell size set (this test will fail if you comment out line 256), so maybe you could clarify the comment? Yes! Will do. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1077#discussion_r1155086332 From mhanl at openjdk.org Sat Apr 1 10:02:26 2023 From: mhanl at openjdk.org (Marius Hanl) Date: Sat, 1 Apr 2023 10:02:26 GMT Subject: RFR: JDK-8305248: TableView not rendered correctly after column is made visible if fixed cell size is set [v2] In-Reply-To: References: Message-ID: > The determined `prefWidth` of a `TableCell` could be `0.0` when a `fixedCellSize` is set. > This happened because the `TableCell` may not have a skin since it was never added to the scene graph yet. > > The fix is to make sure we get the `prefWidth` after the `TableCell` was added to the scene graph. > That is also the reason why the problem only happened the first time and never again after (skin is then already created). Marius Hanl has updated the pull request incrementally with two additional commits since the last revision: - JDK-8305248: Added the tests also for TreeTableRow - JDK-8305248: Improve comments ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1077/files - new: https://git.openjdk.org/jfx/pull/1077/files/a53ffaa9..703115c5 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1077&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1077&range=00-01 Stats: 72 lines in 3 files changed: 57 ins; 5 del; 10 mod Patch: https://git.openjdk.org/jfx/pull/1077.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1077/head:pull/1077 PR: https://git.openjdk.org/jfx/pull/1077 From kcr at openjdk.org Sat Apr 1 11:58:34 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 1 Apr 2023 11:58:34 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v10] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 23:04:58 GMT, John Neffenger wrote: >> This pull request allows for reproducible builds of JavaFX on Linux, macOS, and Windows by defining the `SOURCE_DATE_EPOCH` environment variable. For example, the following commands create a reproducible build: >> >> >> $ export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) >> $ bash gradlew sdk jmods javadoc >> $ strip-nondeterminism -v -T $SOURCE_DATE_EPOCH build/jmods/*.jmod >> >> >> The three commands: >> >> 1. set the build timestamp to the date of the latest source code change, >> 2. build the JavaFX SDK libraries, JMOD archives, and API documentation, and >> 3. recreate the JMOD files with stable file modification times and ordering. >> >> The third command won't be necessary once Gradle can build the JMOD archives or the `jmod` tool itself has the required support. For more information on the environment variable, see the [`SOURCE_DATE_EPOCH`][1] page. For more information on the command to recreate the JMOD files, see the [`strip-nondeterminism`][2] repository. I'd like to propose that we allow for reproducible builds in JavaFX 17 and consider making them the default in JavaFX 18. >> >> #### Fixes >> >> There are at least four sources of non-determinism in the JavaFX builds: >> >> 1. Build timestamp >> >> The class `com.sun.javafx.runtime.VersionInfo` in the JavaFX Base module stores the time of the build. Furthermore, for builds that don't run on the Hudson continuous integration tool, the class adds the build time to the system property `javafx.runtime.version`. >> >> 2. Modification times >> >> The JAR, JMOD, and ZIP archives store the modification time of each file. >> >> 3. File ordering >> >> The JAR, JMOD, and ZIP archives store their files in the order returned by the file system. The native shared libraries also store their object files in the order returned by the file system. Most file systems, though, do not guarantee the order of a directory's file listing. >> >> 4. Build path >> >> The class `com.sun.javafx.css.parser.Css2Bin` in the JavaFX Graphics module stores the absolute path of its `.css` input file in the corresponding `.bss` output file, which is then included in the JavaFX Controls module. >> >> This pull request modifies the Gradle and Groovy build files to fix the first three sources of non-determinism. A later pull request can modify the Java files to fix the fourth. >> >> [1]: https://reproducible-builds.org/docs/source-date-epoch/ >> [2]: https://salsa.debian.org/reproducible-builds/strip-nondeterminism > > John Neffenger has updated the pull request incrementally with one additional commit since the last revision: > > Support JDK 17 GA or later for building JavaFX I'd like to see this get in soon. I'll do some test builds next week. ------------- PR Comment: https://git.openjdk.org/jfx/pull/446#issuecomment-1492948750 From kcr at openjdk.org Sat Apr 1 12:21:23 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 1 Apr 2023 12:21:23 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: <0GBK0AkOGmtrjhDfXiCQlYalXUKrbwYaltbUGwxA8Ik=.61e63c4c-5819-4d99-a831-1f0d186ebfc4@github.com> On Mon, 27 Mar 2023 14:24:42 GMT, John Hendrikx wrote: > BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. > > When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. > > This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. This seems like a pretty straight-forward change. @hjohn can you add a (short) description of the fix to the PR? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1071#issuecomment-1492955496 From jhendrikx at openjdk.org Sat Apr 1 12:25:23 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 1 Apr 2023 12:25:23 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: <0GBK0AkOGmtrjhDfXiCQlYalXUKrbwYaltbUGwxA8Ik=.61e63c4c-5819-4d99-a831-1f0d186ebfc4@github.com> References: <0GBK0AkOGmtrjhDfXiCQlYalXUKrbwYaltbUGwxA8Ik=.61e63c4c-5819-4d99-a831-1f0d186ebfc4@github.com> Message-ID: On Sat, 1 Apr 2023 12:18:49 GMT, Kevin Rushforth wrote: > This seems like a pretty straight-forward change. > > @hjohn can you add a (short) description of the fix to the PR? I've updated the description. This fix is already incorporated in another PR as well (the PseudoClassState caching) and those can be updated if this makes it in. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1071#issuecomment-1492956322 From kcr at openjdk.org Sat Apr 1 12:41:26 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 1 Apr 2023 12:41:26 GMT Subject: RFR: JDK-8269921 Text in Textflow and listeners on bounds can cause endless loop/crash and other performance issues [v4] In-Reply-To: References: Message-ID: On Wed, 21 Sep 2022 12:05:25 GMT, Florian Kirmaier wrote: >> Florian Kirmaier has updated the pull request incrementally with one additional commit since the last revision: >> >> JDK-8269921 >> Reverted the change to the layout, so we can fix the main-bug without further discussions. > > The simple null check helps in this case. > But sometimes I see the exception, posted by @Maran23 . > So the root cause is probably not fixed - but the symptoms are. > I guess, this PR is then a good progress. > > Imo the main issue is, that having listeners on the bounds causes a change in the behavior of TextFlow and Group - causing unpredictable behavior. @FlorianKirmaier this one fell off my radar. The updated fix seems fine as long the check for null `runs` isn't making some other problem. Btw, the title of the bug doesn't match the problem being fixed, so I recommend changing it to something like "TextFlow: listeners on bounds can throw NPE while computing text bounds". ------------- PR Comment: https://git.openjdk.org/jfx/pull/564#issuecomment-1492959231 From kcr at openjdk.org Sat Apr 1 12:46:28 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 1 Apr 2023 12:46:28 GMT Subject: RFR: 8278021: Fix warnings in macOS glass native code and treat warnings as errors [v2] In-Reply-To: References: <3Tr4lhOlGVVrqdBCTLiumLpqQHEBU8lKhZtz-R1Eh-0=.c973b5f9-62ba-487a-a989-7910b09e3592@github.com> Message-ID: On Tue, 21 Feb 2023 15:18:27 GMT, Martin Fox wrote: >> Turning on warnings-as-errors for the macOS glass native code. Deprecated declarations are excluded and still appear as warnings. >> >> In the code that tries to locate the application's dock icon there were three instances where `NO` was being passed into a method that required a pointer to a `BOOL`, not a `BOOL`. I suspect the intent was to check that the path pointed to an existing file but not a directory. Since JavaFX has gone this long without screening out directories correctly I decided not to fix that behavior except at the very end. >> >> The only other changes of note are sending some NSNotification objects to delegate API's that require them even though we know they're ignored on the other side. It was the easiest way to get rid of the warning. > > Martin Fox has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains two commits: > > - Merge remote-tracking branch 'upstream/master' into macerrors > - Mac Glass treats errors as warnings except for deprecated declarations I'll review this. The large number of warnings can hide a real issue (which I noticed the other day while working on a bug). ------------- PR Comment: https://git.openjdk.org/jfx/pull/687#issuecomment-1492960142 From kcr at openjdk.org Sat Apr 1 12:49:29 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 1 Apr 2023 12:49:29 GMT Subject: RFR: 8273743: KeyCharacterCombination for "+" does not work on US QWERTY keyboard layout [v3] In-Reply-To: References: Message-ID: On Tue, 21 Feb 2023 17:09:32 GMT, Martin Fox wrote: >> The algorithm in `KeyCharacterCombination.match` relies on the call `Toolkit.getKeyCodeForChar` which is difficult to implement correctly. It defies the way most keyboard API?s work and no platform has got it right yet. In particular the Mac and Linux implementations have to resort to a brute-force approach which monitors keystrokes to learn the relationship between keys and characters. >> >> This PR introduces an alternative mechanism which directly asks the platform whether a given key can generate a specific character. It also allows the platform to attach identifying key information to each KeyEvent to make it easier to answer the question (much, much easier). >> >> This is mostly dumb plumbing. On the front-end there?s a new call `View.notifyKeyEx` that takes an additional platform-specific `hardwareCode` parameter. It also returns a boolean indicating whether the event was consumed or not so I can fix JDK-8087863. If you want to follow the path visit the files in this order: >> >> View.java >> GlassViewEventHandler.java >> TKSceneListener.java >> Scene.java >> >> The `KeyEvent` class has been expanded with an additional `hardwareCode` member that can only be accessed internally. See KeyEvent.java and KeyEventHelper.java. >> >> On the back-end `KeyCharacterCombination.match` calls a new routine `Toolkit.getKeyCanGenerateCharacter` which unpacks the `KeyEvent` information and sends it on to the Application. The default implementation falls back to the old `getKeyCodeForChar` call but platform specific Applications can send it on to the native glass code. >> >> KeyCharacterCombination.java >> Toolkit.java >> QuantumToolkit.java >> Application.java >> GtkApplication.java >> >> The glass code can use the `hardwareCode` to answer the question directly. It also has enough information to fall back on the old `getKeyCodeForChar` logic while also enabling the keypad (a common complaint is that Ctrl+?+? only works on the main keyboard and not the keypad, see JDK-8090275). >> >> This PR improves the situation for key events generated by keystrokes. Manually constructed key events won?t work any better or worse than they already do. Based on the bug database I don't think this is an issue. > > Martin Fox has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains three commits: > > - Merge remote-tracking branch 'upstream/master' into scancode > - Added manual test for KeyCharacterCombination matching > - New KeyCharacterCombination implementation @andy-goryachev-oracle or @jperedadnr would one of you also be able to review this? ------------- PR Comment: https://git.openjdk.org/jfx/pull/694#issuecomment-1492960711 From kcr at openjdk.org Sat Apr 1 12:50:29 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 1 Apr 2023 12:50:29 GMT Subject: RFR: 8278938: [Win] Robot can target wrong key for punctuation and symbols [v2] In-Reply-To: References: Message-ID: <_p7L08XExZcHneKE8F5pA3yDXweaIYVuIrbEcg17Un0=.e60d7d25-99da-4000-8091-b75c9c84fd44@github.com> On Wed, 12 Jan 2022 20:45:02 GMT, Martin Fox wrote: >> When processing a `WM_CHAR` event on an OEM key (punctuation, symbol, dead key) the glass code will dynamically query the key's unshifted character to determine the Java code to assign to it. This is necessary since the relationship between OEM key codes and the characters they generate varies from layout to layout. >> >> The Robot implementation was consulting a table which assumed a fixed relationship between Java codes and Windows key codes even for the OEM keys. The table was also missing entries for any Java code not on a US QWERTY layout, like PLUS. >> >> In this PR if we don't find the Java code in the table or if it maps to an OEM key (which may be wrong) we sweep through all the OEM keys looking for the matching Java code. > > Martin Fox has updated the pull request incrementally with one additional commit since the last revision: > > A Robot now correctly handles KeyCodes that aren't in the current layout @andy-goryachev-oracle or @jperedadnr would one of you also be able to review this? ------------- PR Comment: https://git.openjdk.org/jfx/pull/702#issuecomment-1492960947 From kcr at openjdk.org Sat Apr 1 12:51:25 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 1 Apr 2023 12:51:25 GMT Subject: RFR: 8278924: [Linux] Robot key test can fail if multiple keyboard layouts are installed In-Reply-To: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> References: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> Message-ID: On Mon, 17 Jan 2022 20:25:08 GMT, Martin Fox wrote: > The Robot implementation on Linux did not consult the current layout when mapping from a KeyCode to a hardware code. Internally it retrieved results for all the layouts but just picked the first one it saw leading to random effects. Though not part of the original bug report, the code also ignored the shift level when choosing which result to pick. On a French layout the dollar sign is on two keys (AltGr 4 is the second one) and the code could choose either one. Same is true for pound. > > This PR consults the current layout and only on shift level 0 which is the same level used in get_glass_key to figure out which KeyCode to assign when generating a KeyEvent. @tsayao or @andy-goryachev-oracle or @jperedadnr would one of you also be able to review this? ------------- PR Comment: https://git.openjdk.org/jfx/pull/718#issuecomment-1492961090 From kcr at openjdk.org Sat Apr 1 13:02:29 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 1 Apr 2023 13:02:29 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: References: Message-ID: On Tue, 21 Mar 2023 22:49:34 GMT, Martin Fox wrote: >> This PR adds code to ensure that KeyCodeCombinations match KeyEvents as expected by more accurately mapping from a Mac key code to a Java key code based on the user?s active keyboard layout (the existing code assumes a US QWERTY layout). The new code first identifies a set of Mac keys which can produce different characters based on the user?s keyboard layout. A Mac key code outside that area is processed exactly as before. For a key inside the layout-sensitive area the code calls UCKeyTranslate to translate the key to an unshifted ASCII character based on the active keyboard and uses that to determine the Java key code. >> >> When performing the reverse mapping for the Robot the code first uses the old QWERTY mapping to find a candidate key. If it lies in the layout-sensitive area the code then scans the entire area calling UCKeyTranslate until it finds a match. If the key lies outside the layout-sensitive area it?s processed exactly as before. >> >> There are multiple duplicates of these bugs logged against Mac applications built with JavaFX. >> >> https://bugs.openjdk.java.net/browse/JDK-8090257 Mac: Inconsistent KeyEvents with alternative keyboard layouts >> https://bugs.openjdk.java.net/browse/JDK-8088120 [Accelerator, Mac] CMD + Z accelerator is not working with French keyboard >> https://bugs.openjdk.java.net/browse/JDK-8087915 Mac: accelerator doesn't take into account azerty keyboard layout >> https://bugs.openjdk.java.net/browse/JDK-8150709 Mac OSX and German Keyboard Layout (Y/Z) > > Martin Fox has updated the pull request incrementally with one additional commit since the last revision: > > Added manual cross-platform keyboard handling test @andy-goryachev-oracle or @johanvos or @jperedadnr can one of you also help review and test this? ------------- PR Comment: https://git.openjdk.org/jfx/pull/425#issuecomment-1492963630 From kevin.rushforth at oracle.com Sat Apr 1 13:08:27 2023 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Sat, 1 Apr 2023 06:08:27 -0700 Subject: Allow OpenJFX to be built on unknown architectures In-Reply-To: <4ad51ddc-2638-9b21-c6cb-d3498f760154@status6.com> References: <4ad51ddc-2638-9b21-c6cb-d3498f760154@status6.com> Message-ID: <7b6978f3-e540-7145-5410-d5f11c8726ff@oracle.com> Or, rather than removing the check entirely, make it a warning. -- Kevin On 3/31/2023 9:03 AM, John Neffenger wrote: > On 3/30/23 11:17 AM, Glavo wrote: >> I compiled OpenJFX for RISC-V and MIPS64el platforms with reference >> to your patch, thereby porting our JavaFX applications to these >> platforms, and it worked well. > > A better patch, then, would be to remove the platform test entirely so > that there are no unsupported build architectures. In other words, > remove this failure: > > ? fail("Unknown and unsupported build architecture: $OS_ARCH") > > My current patch is too conservative and just extends the list of > supported architectures. I'll keep that in mind when I create the pull > request (unless anyone else beats me to it). > > allow-armhf-i386-ppc64el-s390x.patch > https://github.com/jgneff/openjfx/blob/edge/snap/local/allow-armhf-i386-ppc64el-s390x.patch > > > Thanks, > John > From kcr at openjdk.org Sat Apr 1 14:01:24 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 1 Apr 2023 14:01:24 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 In-Reply-To: References: Message-ID: On Fri, 31 Mar 2023 07:57:11 GMT, Hima Bindu Meda wrote: > In Jenkins Build, the intermediate failure on windows is observed due to crash in mspdbserv.exe, which generates Program database (.pdb) files. > Disabled the pdb file generation in order to resolve the build failure. > Sanity testing looks fine. Verified build on windows, mac and linux. I'll do some additional testing early next week. I do have one quick request: Rather than removing or commenting out the compiler and linker flags, can you use `if (PORT STREQUAL "Java")` (or `if (NOT PORT STREQUAL "Java")`) as was done in #1073 ? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1079#issuecomment-1492977290 From kcr at openjdk.org Sat Apr 1 14:21:30 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 1 Apr 2023 14:21:30 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v9] In-Reply-To: References: Message-ID: On Wed, 11 Jan 2023 23:11:59 GMT, John Neffenger wrote: >> I'll need a bit more time to run CI test builds again. I'm thinking it might be better to get this in early in JavaFX 21 rather than late in JavaFX 20 anyway. > >> I'll need a bit more time to run CI test builds again. I'm thinking it might be better to get this in early in JavaFX 21 rather than late in JavaFX 20 anyway. > > I agree, especially considering the change required for JDK 17 GA. Besides, we're not going to have full cross-system reproducible builds until we start building JavaFX with JDK 20 due to [Bug JDK-8292892](https://bugs.openjdk.org/browse/JDK-8292892). @jgneff Can you merge in the latest `master`? I'll do this in my test branch, but it would still be helpful. ------------- PR Comment: https://git.openjdk.org/jfx/pull/446#issuecomment-1492983914 From jhendrikx at openjdk.org Sat Apr 1 14:29:29 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 1 Apr 2023 14:29:29 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v6] In-Reply-To: References: Message-ID: On Sat, 18 Feb 2023 23:35:40 GMT, Nir Lisker wrote: >> John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix no change detection >> >> Old text was uppercased while new text is always lowercase. > > With this test > > static void with2Changes() { > inv = 0; > var property = new SimpleIntegerProperty(0); > > ChangeListener listenerA = (obs, ov, nv) -> { > inv++; > String spaces = spaces(); > System.out.println(spaces + " bA " + ov + "->" + nv + " (" + property.get() + ")"); > property.set(5); > System.out.println(spaces + " aA " + ov + "->" + nv + " (" + property.get() + ")"); > }; > > ChangeListener listenerB = (obs, ov, nv) -> { > inv++; > String spaces = spaces(); > System.out.println(spaces + " bB " + ov + "->" + nv + " (" + property.get() + ")"); > property.set(6); > System.out.println(spaces + " aB " + ov + "->" + nv + " (" + property.get() + ")"); > }; > > property.addListener(listenerA); > property.addListener(listenerB); > > property.set(1); > } > > I get > > 1 bA 0->1 (1) > 1 aA 0->1 (5) > 2 bB 0->1 (5) > 2 aB 0->1 (6) > 3 bA 1->6 (6) > 3 aA 1->6 (5) > 4 bB 1->6 (5) > 4 aB 1->6 (6) > > I think that we are missing a 1->5 event originating in listener A, and maybe a 5->6 event. I'm honestly not sure what the behavior should be here. @nlisker @mstr2 I'm going to update this soon with an (IMHO) **much** better solution, that handles all the edge cases. - Recursive algorithm, listeners with a higher index get a summarized change if earlier listeners are changing values - No copying of listener lists ever occurs; instead, removing listeners is deferred (they're `null`-ed), and only removed when no notifications are running - This also means that a removed listener is immediately disabled as it is not part of some copy, so they will **never** receive another notification, nested or otherwise - An added listener is immediately added and will receive notifications immediately from the top level notification loop (nested loops never get that far as nested loops are stopped when they reach the same index as a higher level loop) - If after a top level notification completes it was discovered that one or more listeners were removed, the listener list is compacted (removing null elements) -- order is maintained (too much depends on it. This isn't a copy, but could be optimized if there were many removals (could use `removeIf` for this purpose which may be optimized for `ArrayList`). The implementation has the following characteristics: 1. For change listeners, the old value received is always the previous new value. 2. The new value received always matches property.getValue() 3. Listeners with a higher index receive less change events when earlier listeners make changes, but the events are all consistent 4. A removed listener will not get another notification 5. An added listener will receive its first notification immediately, although will not see all the nested changes going on (it is the last listener after all, so item (3) applies) 6. As said, no copying or locking of lists Here's a sample output with 5 listeners, where 0, 2 and 4 just register changes, and 1 uppercases a String and 3 will ensure the String contains 2 characters: Notifying 0 of change from A to b Notifying 1 of change from A to b (listener 1 uppercases "b") Notifying 0 of change from b to B Notifying 1 of change from b to B Notifying 2 of change from A to B Notifying 3 of change from A to B (listener 3 adds a character "B" -> "Bb") Notifying 0 of change from B to Bb Notifying 1 of change from B to Bb (listener 1 uppercases "Bb") Notifying 0 of change from Bb to BB Notifying 1 of change from Bb to BB Notifying 2 of change from B to BB Notifying 3 of change from B to BB Notifying 4 of change from A to BB As you can see, all changes make sense and the final listener only receives the full change. ------------- PR Comment: https://git.openjdk.org/jfx/pull/837#issuecomment-1492986002 From mstrauss at openjdk.org Sat Apr 1 18:14:11 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 1 Apr 2023 18:14:11 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v4] In-Reply-To: References: Message-ID: > `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. > > 1. `removeAll(c)`: > This is a no-op if 'c' is empty. > For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. > > 2. `retainAll(c)`: > This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. > > I've added some tests to verify the optimized behavior for each of the three classes. Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: addressed review comments, added tests ------------- Changes: - all: https://git.openjdk.org/jfx/pull/751/files - new: https://git.openjdk.org/jfx/pull/751/files/682bdf80..6ea639b6 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=751&range=03 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=751&range=02-03 Stats: 464 lines in 10 files changed: 207 ins; 34 del; 223 mod Patch: https://git.openjdk.org/jfx/pull/751.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/751/head:pull/751 PR: https://git.openjdk.org/jfx/pull/751 From mstrauss at openjdk.org Sat Apr 1 18:29:32 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 1 Apr 2023 18:29:32 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v3] In-Reply-To: References: Message-ID: <1SDOvNpYA9-hWQyQ0lzho3QxRod82jUNZusUd8z27qY=.a01d9094-ce8d-4608-ad66-2e99932417d2@github.com> On Sat, 1 Apr 2023 08:00:33 GMT, John Hendrikx wrote: >> Michael Strau? has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains five commits: >> >> - Merge branch 'master' into fixes/JDK-8283063 >> >> # Conflicts: >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableListWrapper.java >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableMapWrapper.java >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSequentialListWrapper.java >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSetWrapper.java >> - address review comments >> - refactored removeAll/retainAll optimizations >> - Optimize removeAll/retainAll for Observable{List/Set/Map}Wrapper >> - Failing test > > modules/javafx.base/src/main/java/javafx/collections/ModifiableObservableListBase.java line 142: > >> 140: >> 141: return; >> 142: } > > I'm really happy you also added the index range checks, not only does it conform to the contract better, it will help expose bugs in caller code (or even the JavaFX code as Observable* classes are used in many places, and who knows what bugs might lurk in some of the more complicated classes). > > I'm not quite sure how this check is suppose to work though; does this need a comment ? > Suggestion: > > if (fromIndex == toIndex) { // distinguish between the clear and remove(int) call > if (fromIndex < 0 || fromIndex > size()) { > throw new IndexOutOfBoundsException("Index: " + fromIndex); > } > > return; > } > > > I think that would be a bit too cryptic for me... The index check is only really necessary for the optimized code path, since calling `listIterator` later in the method would catch an invalid index. However, I've opted to always check the index at the beginning of the method. > modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableSequentialListWrapperTest.java line 60: > >> 58: >> 59: @Test >> 60: public void testAddAllWithEmptyCollectionArgumentAndInvalidIndexThrowsIOOBE() { > > How about a variant that doesn't pass an empty collection, `-1` should still fail, and for example `100` should also fail. Done. > modules/javafx.base/src/test/java/test/javafx/collections/ModifiableObservableListBaseTest.java line 61: > >> 59: >> 60: @Test >> 61: public void testAddAllWithEmptyCollectionArgumentAndInvalidIndexThrowsIOOBE() { > > Could use variant here I think with a non empty collection, and see if it still throws IOOBE. Done. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155152703 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155153010 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155152937 From mstrauss at openjdk.org Sat Apr 1 18:34:25 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 1 Apr 2023 18:34:25 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v4] In-Reply-To: References: Message-ID: <94HQ_9GvF_0FkethQ_MVSt_3mtCXHjaj0asb_3FTzAA=.e34061cd-195f-4fb8-b22e-3d184f35a969@github.com> On Sat, 1 Apr 2023 18:14:11 GMT, Michael Strau? wrote: >> `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. >> >> 1. `removeAll(c)`: >> This is a no-op if 'c' is empty. >> For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. >> >> 2. `retainAll(c)`: >> This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. >> >> I've added some tests to verify the optimized behavior for each of the three classes. > > Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: > > addressed review comments, added tests I've added comments in all places where implicit null checks are important to satisfy the collection contract. In addition to that, I've also re-organized the tests using nested test classes, and added explicit null tests for all relevant code paths. ------------- PR Comment: https://git.openjdk.org/jfx/pull/751#issuecomment-1493068555 From mstrauss at openjdk.org Sat Apr 1 18:34:32 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 1 Apr 2023 18:34:32 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v3] In-Reply-To: References: Message-ID: On Sat, 1 Apr 2023 07:32:20 GMT, John Hendrikx wrote: >> Michael Strau? has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains five commits: >> >> - Merge branch 'master' into fixes/JDK-8283063 >> >> # Conflicts: >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableListWrapper.java >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableMapWrapper.java >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSequentialListWrapper.java >> # modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSetWrapper.java >> - address review comments >> - refactored removeAll/retainAll optimizations >> - Optimize removeAll/retainAll for Observable{List/Set/Map}Wrapper >> - Failing test > > modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableMapWrapper.java line 326: > >> 324: if (backingMap.isEmpty()) { >> 325: return false; >> 326: } > > Passing `null` is always an error, and I think here you still need to throw an NPE first when `c` is `null`, even if the backing map is empty. From `AbstractColection` for example: > > public boolean retainAll(Collection c) { > Objects.requireNonNull(c); > > ... > > I realize this was already incorrect, so perhaps out of scope for your PR. I've fixed problems like this and added comments in all places where a null check is important. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155153443 From jhendrikx at openjdk.org Sat Apr 1 22:16:26 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 1 Apr 2023 22:16:26 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v4] In-Reply-To: References: Message-ID: On Sat, 1 Apr 2023 18:14:11 GMT, Michael Strau? wrote: >> `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. >> >> 1. `removeAll(c)`: >> This is a no-op if 'c' is empty. >> For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. >> >> 2. `retainAll(c)`: >> This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. >> >> I've added some tests to verify the optimized behavior for each of the three classes. > > Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: > > addressed review comments, added tests Looks really good now! ------------- Marked as reviewed by jhendrikx (Committer). PR Review: https://git.openjdk.org/jfx/pull/751#pullrequestreview-1367949991 From nlisker at openjdk.org Sun Apr 2 01:17:36 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Sun, 2 Apr 2023 01:17:36 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v4] In-Reply-To: References: Message-ID: On Sat, 1 Apr 2023 18:14:11 GMT, Michael Strau? wrote: >> `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. >> >> 1. `removeAll(c)`: >> This is a no-op if 'c' is empty. >> For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. >> >> 2. `retainAll(c)`: >> This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. >> >> I've added some tests to verify the optimized behavior for each of the three classes. > > Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: > > addressed review comments, added tests Looks good. Left a few minor comments. modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSequentialListWrapper.java line 178: > 176: @Override > 177: public boolean addAll(int index, Collection c) { > 178: if (index < 0 || index > size()) { If you want, there are methods in `Objects` that do range checks, like `Objects.checkIndex`. Same for the other files. modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableListWrapperTest.java line 41: > 39: > 40: @Nested > 41: class RemoveAllTest { Empty line after class declaration. Same for other places. modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableListWrapperTest.java line 57: > 55: }); > 56: > 57: list.removeAll(Collections.emptyList()); You can use `List.of()` instead of `Collections.emptyList()` if you want here and in other places. modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableMapWrapperTest.java line 65: > 63: > 64: @Test > 65: public void testValueSetNullArgumentThrowsNPE() { The values collection is not a `Set`, but the intention is clear. Same in other places. modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableMapWrapperTest.java line 108: > 106: > 107: var map2 = new ObservableMapWrapper<>(new HashMap<>(Map.of("k0", "v0", "k1", "v1", "k2", "v2"))); > 108: assertThrows(NullPointerException.class, () -> map2.entrySet().retainAll((Collection) null)); Would advise to rename `map1` to `emptyMap` and `map2` to `notEmptyMap` or the like. Same in other places. modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableSequentialListWrapperTest.java line 55: > 53: }; > 54: > 55: assertDoesNotThrow(() -> list.addAll(Collections.emptyList())); The `addAll` method here does not belong to `ObservableSequentialListWrapper`, but to `ModifiableObservableListBase`, which is tested in another file. Not sure if this method test helps. ------------- PR Review: https://git.openjdk.org/jfx/pull/751#pullrequestreview-1367987645 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155208556 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155217217 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155217387 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155219827 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155220370 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155219034 From jvos at openjdk.org Sun Apr 2 09:32:24 2023 From: jvos at openjdk.org (Johan Vos) Date: Sun, 2 Apr 2023 09:32:24 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 In-Reply-To: References: Message-ID: <3lKGcPNGOyKZJv6UstI15xDgBR63gCKrng7Lp_k2Uy0=.6e812c60-43cd-4285-86dd-b31a0486ae15@github.com> On Sat, 1 Apr 2023 13:59:02 GMT, Kevin Rushforth wrote: > I'll do some additional testing early next week. I do have one quick request: Rather than removing or commenting out the compiler and linker flags, can you use `if (PORT STREQUAL "Java")` (or `if (NOT PORT STREQUAL "Java")`) as was done in #1073 ? I agree with this remark. Also, do you have insight in why removing the debug flag "fixes" the problem? Are we sure that there is not something wrong below the surface that becomes visible in case (but not necessarily limited to this case) the debug flags are on? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1079#issuecomment-1493278322 From tsayao at openjdk.org Sun Apr 2 20:10:32 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sun, 2 Apr 2023 20:10:32 GMT Subject: RFR: 8303038: Glass gtk3 sends scroll events with delta(x, y) = 0 [v5] In-Reply-To: References: <9H9NFSADpb1CL6zwN-Q8kdJUnId5CcSUo1KlBnTnP0Q=.41ca5b87-ae78-4ef9-89ac-c867a2517533@github.com> Message-ID: On Wed, 1 Mar 2023 22:40:53 GMT, Thiago Milczarek Sayao wrote: >> Simple fix to get the scroll deltas from GDK_SCROLL_SMOOTH. If we ignore this scroll event type, deltas are sent to java with the value equal to zero. >> >> Here's whats happening: >> >> We include all event masks, so when using gtk3 (>= 3.4.0) it includes `GDK_SMOOTH_SCROLL_MASK` meaning we receive duplicated events, one with `direction = GDK_SMOOTH_SCROLL_MASK` and other with "legacy" direction (UP/DOWN). >> >> When receiving the event corresponding to `GDK_SMOOTH_SCROLL_MASK` we ignored it causing it to send deltas (x,y) = 0. >> >> The fix now checks if `GDK_SMOOTH_SCROLL_MASK` is supported and uses it, also adding smooth scroll functionality. > > Thiago Milczarek Sayao has updated the pull request incrementally with one additional commit since the last revision: > > Improve direction Commenting to avoid being closed. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1044#issuecomment-1493428860 From tsayao at openjdk.org Sun Apr 2 20:32:27 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sun, 2 Apr 2023 20:32:27 GMT Subject: RFR: 8223373: Remove IntelliJ IDEA specific files from the source code repository [v5] In-Reply-To: <3zCUdkkbxcB1NMO9-VFrOgALNGa4k2vC0yXoyqYSbyQ=.596e4f9c-9101-4548-9d7e-134f06d1770c@github.com> References: <3zCUdkkbxcB1NMO9-VFrOgALNGa4k2vC0yXoyqYSbyQ=.596e4f9c-9101-4548-9d7e-134f06d1770c@github.com> Message-ID: On Fri, 3 Mar 2023 01:13:49 GMT, Thiago Milczarek Sayao wrote: >> This PR does: >> >> - Remove specific Idea files and let it be imported from gradle; >> - Adds checkstyle (to use with checkstyle plugin - it will let you know style mistakes); >> - Configures auto-format to sun style (with the changes mentioned in [Code Style Rules](https://wiki.openjdk.org/display/OpenJFX/Code+Style+Rules)); >> - Automatically sets Copyright notice (updates year too); >> - Run configurations for samples/toys and builds. > > Thiago Milczarek Sayao has updated the pull request incrementally with two additional commits since the last revision: > > - Revert "Make intellij see :systemTests dependecies" > > This reverts commit dca7eab24958e1214147b7d291f0faf52ea27ddf. > - Make intellij see :systemTests dependecies I agree. I have removed the gradle changes so it's easier to review. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1009#issuecomment-1493433283 From tsayao at openjdk.org Sun Apr 2 20:49:38 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sun, 2 Apr 2023 20:49:38 GMT Subject: RFR: 8260528: Clean glass-gtk sizing and positioning code [v56] In-Reply-To: <5-LHfl6_vdrmRjLivevBopnWBbzgO0ygK1dRPAFdzoM=.22e09b72-4142-4c1c-b320-94a1c48aaa69@github.com> References: <5-LHfl6_vdrmRjLivevBopnWBbzgO0ygK1dRPAFdzoM=.22e09b72-4142-4c1c-b320-94a1c48aaa69@github.com> Message-ID: > This cleans size and positioning code, reducing special cases, code complexity and size. > > Changes: > > - cached extents: 28, 1, 1, 1 are old defaults - modern gnome uses different sizes. It does not assume any size because it varies - it does cache because it's unlikely to vary on the same system - but if it does occur, it will only waste a resize event. > - window geometry, min/max size are centralized in `update_window_constraints`; > - Frame extents (the window decoration size used for "total window size"): > - frame extents are received in `process_property_notify`; > - removed quirks in java code; > - When received, call `set_bounds` again to adjust the size (to account decorations later received); > - Removed `activate_window` because it's the same as focusing the window. `gtk_window_present` will deiconify and focus it. > - `ensure_window_size` was a quirk - removed; > - `requested_bounds` removed - not used anymore; > - `window_configure` incorporated in `set_bounds` with `gtk_window_move` and `gtk_window_resize`; > - `process_net_wm_property` is a work-around for Unity only (added a check if Unity - but it can probably be removed at some point) > - `restack` split in `to_front()` and `to_back()` to conform to managed code; Thiago Milczarek Sayao has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 78 commits: - Merge branch 'master' into clean_glass_gtk - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Fix bug when window starts maximized and restores to wrong size - Minor adjustments - Fix window order - Revert "Fix window order (focus event)" This reverts commit 1ab609906e48ed8fb1b6f229c3afc0d4d2b79472. - Fix window order (focus event) - ... and 68 more: https://git.openjdk.org/jfx/compare/c23d067d...89e4efc6 ------------- Changes: https://git.openjdk.org/jfx/pull/915/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=915&range=55 Stats: 750 lines in 5 files changed: 175 ins; 434 del; 141 mod Patch: https://git.openjdk.org/jfx/pull/915.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/915/head:pull/915 PR: https://git.openjdk.org/jfx/pull/915 From tsayao at openjdk.org Sun Apr 2 22:52:26 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sun, 2 Apr 2023 22:52:26 GMT Subject: RFR: 8278924: [Linux] Robot key test can fail if multiple keyboard layouts are installed In-Reply-To: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> References: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> Message-ID: On Mon, 17 Jan 2022 20:25:08 GMT, Martin Fox wrote: > The Robot implementation on Linux did not consult the current layout when mapping from a KeyCode to a hardware code. Internally it retrieved results for all the layouts but just picked the first one it saw leading to random effects. Though not part of the original bug report, the code also ignored the shift level when choosing which result to pick. On a French layout the dollar sign is on two keys (AltGr 4 is the second one) and the code could choose either one. Same is true for pound. > > This PR consults the current layout and only on shift level 0 which is the same level used in get_glass_key to figure out which KeyCode to assign when generating a KeyEvent. @beldenfox Could you point out which tests were failing? `test.robot.javafx.embed.swing.SwingNodeJDialogTest` is getting stuck for me. ------------- PR Comment: https://git.openjdk.org/jfx/pull/718#issuecomment-1493458661 From mstrauss at openjdk.org Sun Apr 2 23:32:27 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sun, 2 Apr 2023 23:32:27 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v4] In-Reply-To: References: Message-ID: On Sat, 1 Apr 2023 23:28:51 GMT, Nir Lisker wrote: >> Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: >> >> addressed review comments, added tests > > modules/javafx.base/src/main/java/com/sun/javafx/collections/ObservableSequentialListWrapper.java line 178: > >> 176: @Override >> 177: public boolean addAll(int index, Collection c) { >> 178: if (index < 0 || index > size()) { > > If you want, there are methods in `Objects` that do range checks, like `Objects.checkIndex`. > > Same for the other files. In order to use `Objects.checkIndex` here, I would have to call it like this: `Objects.checkIndex(index, size() + 1)`. `size() + 1` is necessary because it is valid to call this method with an `index` equal to the size of the list. However, the exception message that would be produced for an out-of-bounds index would be incorrect, for example when adding elements at index 20 to a list that already contains 10 elements: "Index 20 out of bounds for length 11". Obviously, a list of 10 elements doesn't have a length of 11. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155392501 From duke at openjdk.org Sun Apr 2 23:39:27 2023 From: duke at openjdk.org (Martin Fox) Date: Sun, 2 Apr 2023 23:39:27 GMT Subject: RFR: 8278924: [Linux] Robot key test can fail if multiple keyboard layouts are installed In-Reply-To: References: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> Message-ID: On Sun, 2 Apr 2023 22:49:51 GMT, Thiago Milczarek Sayao wrote: >> The Robot implementation on Linux did not consult the current layout when mapping from a KeyCode to a hardware code. Internally it retrieved results for all the layouts but just picked the first one it saw leading to random effects. Though not part of the original bug report, the code also ignored the shift level when choosing which result to pick. On a French layout the dollar sign is on two keys (AltGr 4 is the second one) and the code could choose either one. Same is true for pound. >> >> This PR consults the current layout and only on shift level 0 which is the same level used in get_glass_key to figure out which KeyCode to assign when generating a KeyEvent. > > @beldenfox Could you point out which tests were failing? > `test.robot.javafx.embed.swing.SwingNodeJDialogTest` is getting stuck for me. @tsayao The best place to start is with the manual test that I added to PR #425 (KeyboardTest.java). That test works on Windows, Mac, and Linux and uses a Robot to throw a whole slew of platform key events at the system and then verify that the right JavaFX KeyEvents come through on the other side. The primary motivation for this PR is to pave the way for future PR's. Accelerators involving punctuation and symbols aren't working at all well on Linux (see [JDK-8273743](https://bugs.openjdk.org/browse/JDK-8273743)) and having a working Robot in hand will be extremely helpful in testing the fixes. The manual test in #425 can also be configured to test KeyCharacterCombinations (the component that's broken) but for now you can ignore all that. Unfortunately the manual test itself is a big chunk of code that needs to be reviewed but it is the first comprehensive test written for JavaFX keyboard handling. I wish I could make it shorter (it looks more complicated than it is) but the only way to test the keyboard system is to press a lot of keys. BTW, the bot that kicked this PR has lousy timing. I'll be out of town for most of the coming week and will be away from my Linux box. ------------- PR Comment: https://git.openjdk.org/jfx/pull/718#issuecomment-1493468548 From mstrauss at openjdk.org Sun Apr 2 23:50:15 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sun, 2 Apr 2023 23:50:15 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v5] In-Reply-To: References: Message-ID: > `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. > > 1. `removeAll(c)`: > This is a no-op if 'c' is empty. > For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. > > 2. `retainAll(c)`: > This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. > > I've added some tests to verify the optimized behavior for each of the three classes. Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: addressed review comments ------------- Changes: - all: https://git.openjdk.org/jfx/pull/751/files - new: https://git.openjdk.org/jfx/pull/751/files/6ea639b6..91260638 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=751&range=04 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=751&range=03-04 Stats: 66 lines in 5 files changed: 0 ins; 8 del; 58 mod Patch: https://git.openjdk.org/jfx/pull/751.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/751/head:pull/751 PR: https://git.openjdk.org/jfx/pull/751 From mstrauss at openjdk.org Sun Apr 2 23:50:22 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sun, 2 Apr 2023 23:50:22 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v4] In-Reply-To: References: Message-ID: On Sun, 2 Apr 2023 00:31:51 GMT, Nir Lisker wrote: >> Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: >> >> addressed review comments, added tests > > modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableListWrapperTest.java line 41: > >> 39: >> 40: @Nested >> 41: class RemoveAllTest { > > Empty line after class declaration. > > Same for other places. I see that all over the JavaFX codebase. Do we have any guidance for that? > modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableListWrapperTest.java line 57: > >> 55: }); >> 56: >> 57: list.removeAll(Collections.emptyList()); > > You can use `List.of()` instead of `Collections.emptyList()` if you want here and in other places. Done. > modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableMapWrapperTest.java line 65: > >> 63: >> 64: @Test >> 65: public void testValueSetNullArgumentThrowsNPE() { > > The values collection is not a `Set`, but the intention is clear. Same in other places. Fixed that. > modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableMapWrapperTest.java line 108: > >> 106: >> 107: var map2 = new ObservableMapWrapper<>(new HashMap<>(Map.of("k0", "v0", "k1", "v1", "k2", "v2"))); >> 108: assertThrows(NullPointerException.class, () -> map2.entrySet().retainAll((Collection) null)); > > Would advise to rename `map1` to `emptyMap` and `map2` to `notEmptyMap` or the like. > > Same in other places. Done. > modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableSequentialListWrapperTest.java line 55: > >> 53: }; >> 54: >> 55: assertDoesNotThrow(() -> list.addAll(Collections.emptyList())); > > The `addAll` method here does not belong to `ObservableSequentialListWrapper`, but to `ModifiableObservableListBase`, which is tested in another file. Not sure if this method test helps. Good catch, I've removed the method test. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155395211 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155394964 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155395046 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155395091 PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155394994 From mstrauss at openjdk.org Sun Apr 2 23:52:23 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sun, 2 Apr 2023 23:52:23 GMT Subject: RFR: JDK-8199216: Memory leak and quadratic layout time with nested nodes (hbox) and pseudo-class in style sheet [v2] In-Reply-To: References: <40ndHnnBPYAx7mytmvt-Qe31S-F7KkBU6jxhEA03QGc=.19921c69-18e2-492c-8b50-782e41ce3b0a@github.com> Message-ID: <-rrLA9w2Q7Kkd93E2-gFXeFiNuzc4f8QnihvyGIU1MM=.1098af8c-53d5-4c58-90b5-1161b2e3c27d@github.com> On Fri, 31 Mar 2023 18:07:08 GMT, John Hendrikx wrote: >> modules/javafx.graphics/src/main/java/com/sun/javafx/css/BitSet.java line 584: >> >>> 582: * @param obj the object to cast, cannot be {@code null} >>> 583: * @return a type T, or {@code null} if the argument was not of this type >>> 584: * @throws NullPointerException when {@code obj} is {@code null} >> >> Previously, this method always returned an instance of `T`. Now that is not the case, it might also simply return `null` if the argument passed into it is an instance of a different class. I think it makes sense to also return `null` when the argument passed into the method is `null`. > > I'm a bit unsure why that would be an improvement. Passing `null` to a function that doesn't expect it should IMHO never just return `null` but should instead be considered a programming error and result in a stack trace. Passing in a non-null value that can't be casted is explicitly documented now that it would result in `null`. One is a caller error, the other isn't IMHO (as the caller can't check if it is castable without another method -- I considered adding an `instanceof` method). > > Or maybe I'm reading too much in to this and you are just pointing out that the function has changed from its previous contract -- I think this is okay as `BitSet` is not public API, nor are any of its subclasses. I found it strange that a method named `cast` would reject `null` as an argument, but will happily return `null` and require the caller to check it. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1076#discussion_r1155395834 From hmeda at openjdk.org Mon Apr 3 05:56:14 2023 From: hmeda at openjdk.org (Hima Bindu Meda) Date: Mon, 3 Apr 2023 05:56:14 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 [v2] In-Reply-To: References: Message-ID: > In Jenkins Build, the intermediate failure on windows is observed due to crash in mspdbserv.exe, which generates Program database (.pdb) files. > Disabled the pdb file generation in order to resolve the build failure. > Sanity testing looks fine. Verified build on windows, mac and linux. Hima Bindu Meda has updated the pull request incrementally with one additional commit since the last revision: Add code under Java port ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1079/files - new: https://git.openjdk.org/jfx/pull/1079/files/0ef66c0b..d21b94a6 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1079&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1079&range=00-01 Stats: 8 lines in 1 file changed: 8 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jfx/pull/1079.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1079/head:pull/1079 PR: https://git.openjdk.org/jfx/pull/1079 From mstrauss at openjdk.org Mon Apr 3 06:25:29 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 3 Apr 2023 06:25:29 GMT Subject: RFR: JDK-8199216: Memory leak and quadratic layout time with nested nodes (hbox) and pseudo-class in style sheet [v3] In-Reply-To: References: Message-ID: On Fri, 31 Mar 2023 21:56:08 GMT, John Hendrikx wrote: >> This fix introduces immutable sets of `PseudoClass` almost everywhere, as they are rarely modified. These are re-used by caching them in a new class `ImmutablePseudoClassSetsCache`. >> >> In order to make this work, `BitSet` had to be cleaned up. It made assumptions about the collections it is given (which may no longer always be another `BitSet`). I also added the appropriate null checks to ensure there weren't any other bugs lurking. >> >> Then there was a severe bug in `toArray` in both the subclasses that implement `BitSet`. >> >> The bug in `toArray` was incorrect use of the variable `index` which was used for both advancing the pointer in the array to be generated, as well as for the index to the correct `long` in the `BitSet`. This must have resulted in other hard to reproduce problems when dealing with `Set` or `Set` if directly or indirectly calling `toArray` (which is for example used by `List.of` and `Set.of`) -- I fixed this bug because I need to call `Set.copyOf` which uses `toArray` -- as the same bug was also present in `StyleClassSet`, I fixed it there as well. >> >> The net result of this change is that there are far fewer `PseudoClassState` objects created; the majority of these are never modified, and the few that are left are where you'd expect to see them modified. >> >> A test with 160 nested HBoxes which were given the hover state shows a 99.99% reduction in `PseudoClassState` instances and a 70% reduction in heap use (220 MB -> 68 MB), see the linked ticket for more details. >> >> Although the test case above was extreme, this change should have positive effects for most applications. > > John Hendrikx has updated the pull request incrementally with three additional commits since the last revision: > > - Base BitSet on AbstractSet to inherit correct equals/hashCode/toArray > > - Removed faulty toArray implementations in PseudoClassState and > StyleClassSet > - Added test that verifies equals/hashCode for PseudoClassState respect > Set contract now > - Made getBits package private so it can't be inherited > - Remove unused code > - Ensure Match doesn't allow modification modules/javafx.graphics/src/main/java/com/sun/javafx/css/ImmutablePseudoClassSetsCache.java line 53: > 51: return CACHE.computeIfAbsent( > 52: Objects.requireNonNull(pseudoClasses, "pseudoClasses cannot be null"), > 53: k -> Set.copyOf(pseudoClasses) The call to `computeIfAbsent` will always do the following things: 1. Capture the `pseudoClasses` argument 2. Call `Map.get` internally 3. ...which calls `Set.hashCode` 4. ...which, for `AbstractSet.hashCode`, iterates over the entire set using an iterator and calls `hashCode` for each element. Since there is no fast path, I wonder whether this may have negative performance implications for larger scene graphs. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1076#discussion_r1155524739 From mstrauss at openjdk.org Mon Apr 3 06:32:32 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 3 Apr 2023 06:32:32 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: On Mon, 27 Mar 2023 14:24:42 GMT, John Hendrikx wrote: > BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. > > When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. > > This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. modules/javafx.graphics/src/main/java/com/sun/javafx/css/BitSet.java line 603: > 601: @Override > 602: public void removeListener(SetChangeListener setChangeListener) { > 603: if (setChangeListener != null) { Even if not explicitly specified for `ObservableSet.removeListener(SetChangeListener)`, implementations generally reject `null` arguments by throwing NPE. This is the default behavior of `SetListenerHelper`. modules/javafx.graphics/src/main/java/com/sun/javafx/css/BitSet.java line 617: > 615: @Override > 616: public void removeListener(InvalidationListener invalidationListener) { > 617: if (invalidationListener != null) { `Observable.removeListener(InvalidationListener)` is specified to reject `null` by throwing NPE. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1155529474 PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1155529800 From jhendrikx at openjdk.org Mon Apr 3 07:15:30 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 3 Apr 2023 07:15:30 GMT Subject: RFR: JDK-8199216: Memory leak and quadratic layout time with nested nodes (hbox) and pseudo-class in style sheet [v3] In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 06:22:39 GMT, Michael Strau? wrote: >> John Hendrikx has updated the pull request incrementally with three additional commits since the last revision: >> >> - Base BitSet on AbstractSet to inherit correct equals/hashCode/toArray >> >> - Removed faulty toArray implementations in PseudoClassState and >> StyleClassSet >> - Added test that verifies equals/hashCode for PseudoClassState respect >> Set contract now >> - Made getBits package private so it can't be inherited >> - Remove unused code >> - Ensure Match doesn't allow modification > > modules/javafx.graphics/src/main/java/com/sun/javafx/css/ImmutablePseudoClassSetsCache.java line 53: > >> 51: return CACHE.computeIfAbsent( >> 52: Objects.requireNonNull(pseudoClasses, "pseudoClasses cannot be null"), >> 53: k -> Set.copyOf(pseudoClasses) > > The call to `computeIfAbsent` will always do the following things: > 1. Capture the `pseudoClasses` argument > 2. Call `Map.get` internally > 3. ...which calls `Set.hashCode` > 4. ...which, for `AbstractSet.hashCode`, iterates over the entire set using an iterator and calls `hashCode` for each element. > > Since there is no fast path, I wonder whether this may have negative performance implications for larger scene graphs. I don't think there is much of an impact, scene graph size should not affect it. The sets involved are tiny, usually consisting of 1 or 2 items and very rarely 3 or possibly more(*). The hash code of `PseudoClass` is very fast, as they're singletons which don't override their hash code. (*) The sets are based on pseudo class combinations encountered in a Scene that would have an active role in changing the control's visual appearance. A pseudo class that doesn't affect appearance is filtered. This means usually only states like `hovered`, `focused` or `armed` have an affect. A class like `focused-within` would only be part of the set if the control involved has styles based on that class that would affect its appearance. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1076#discussion_r1155561513 From jhendrikx at openjdk.org Mon Apr 3 07:21:36 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 3 Apr 2023 07:21:36 GMT Subject: RFR: JDK-8199216: Memory leak and quadratic layout time with nested nodes (hbox) and pseudo-class in style sheet [v2] In-Reply-To: <-rrLA9w2Q7Kkd93E2-gFXeFiNuzc4f8QnihvyGIU1MM=.1098af8c-53d5-4c58-90b5-1161b2e3c27d@github.com> References: <40ndHnnBPYAx7mytmvt-Qe31S-F7KkBU6jxhEA03QGc=.19921c69-18e2-492c-8b50-782e41ce3b0a@github.com> <-rrLA9w2Q7Kkd93E2-gFXeFiNuzc4f8QnihvyGIU1MM=.1098af8c-53d5-4c58-90b5-1161b2e3c27d@github.com> Message-ID: On Sun, 2 Apr 2023 23:49:55 GMT, Michael Strau? wrote: >> I'm a bit unsure why that would be an improvement. Passing `null` to a function that doesn't expect it should IMHO never just return `null` but should instead be considered a programming error and result in a stack trace. Passing in a non-null value that can't be casted is explicitly documented now that it would result in `null`. One is a caller error, the other isn't IMHO (as the caller can't check if it is castable without another method -- I considered adding an `instanceof` method). >> >> Or maybe I'm reading too much in to this and you are just pointing out that the function has changed from its previous contract -- I think this is okay as `BitSet` is not public API, nor are any of its subclasses. > > I found it strange that a method named `cast` would reject `null` as an argument, but will happily return `null` and require the caller to check it. The name might need updating, although when the name can't cover the exact intended functionality, the docs are supposed to explain all the details. I may not need the cast at all anymore; I think the class is just asking for casts to satisfy some generic code, but that shouldn't be relevant. All I would really need is an instanceof check. I'll have another look. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1076#discussion_r1155568508 From fkirmaier at openjdk.org Mon Apr 3 07:25:37 2023 From: fkirmaier at openjdk.org (Florian Kirmaier) Date: Mon, 3 Apr 2023 07:25:37 GMT Subject: RFR: 8277848 Binding and Unbinding to List leads to memory leak [v9] In-Reply-To: <8RUj3XOzNWoEW-dlrHtUBIdMD7HgjH_6J3WrPW1kAoE=.b94ab007-8e17-4412-b19e-cf9f60d0e033@github.com> References: <8RUj3XOzNWoEW-dlrHtUBIdMD7HgjH_6J3WrPW1kAoE=.b94ab007-8e17-4412-b19e-cf9f60d0e033@github.com> Message-ID: On Thu, 26 Jan 2023 08:54:44 GMT, Florian Kirmaier wrote: >> Making the initial listener of the ListProperty weak fixes the problem. >> The same is fixed for Set and Map. >> Due to a smart implementation, this is done without any performance drawback. >> (The trick is to have an object, which is both the WeakReference and the Changelistener) >> By implying the same trick to the InvalidationListener, this should even improve the performance of the collection properties. > > Florian Kirmaier has updated the pull request incrementally with one additional commit since the last revision: > > JDK-8277848 > Removed print statements I would like to keep this PR. It's already been approved by one person. ------------- PR Comment: https://git.openjdk.org/jfx/pull/689#issuecomment-1493812314 From jhendrikx at openjdk.org Mon Apr 3 07:26:26 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 3 Apr 2023 07:26:26 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 06:29:29 GMT, Michael Strau? wrote: >> BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. >> >> When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. >> >> This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. > > modules/javafx.graphics/src/main/java/com/sun/javafx/css/BitSet.java line 603: > >> 601: @Override >> 602: public void removeListener(SetChangeListener setChangeListener) { >> 603: if (setChangeListener != null) { > > Even if not explicitly specified for `ObservableSet.removeListener(SetChangeListener)`, implementations generally reject `null` arguments by throwing NPE. This is the default behavior of `SetListenerHelper`. I could remove these checks in this PR, or as part of the larger `BitSet` clean-up PR. The extra check doesn't break anything though, while this PR is mainly focused on fixing a long standing bug that everyone dealing with `ObservableSet` can encounter currently. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1155572378 From fkirmaier at openjdk.org Mon Apr 3 07:29:28 2023 From: fkirmaier at openjdk.org (Florian Kirmaier) Date: Mon, 3 Apr 2023 07:29:28 GMT Subject: RFR: 8299423: JavaFX Mac system menubar leaks [v5] In-Reply-To: References: Message-ID: On Fri, 13 Jan 2023 09:18:56 GMT, Florian Kirmaier wrote: >> This PR fixes the leak in the mac system menu bar. >> >> Inside the native code, NewGlobalRef is called for the callable. >> Which makes it into a "GC-Root" until DeleteGlobalRef is called. >> >> The DeleteGlobalRef is never called for the MenuEntry, if it's removed from the menu without removing it's callable. >> This PR adds logic, whether the Menu is inserted. If it's not inserted in a Menu anymore, then DeleteGlobalRef is called, by calling `_setCallback` with the callable "null". >> >> The unit test verifies, that this bug happened without this change, but no longer happens with this change. > > Florian Kirmaier has updated the pull request incrementally with one additional commit since the last revision: > > JDK-8299423 > we now use the junit5 api I would like to keep this PR. It's already been reviewed by 1 person. The 2 comments in the mailing list don't really relate to this PR. ------------- PR Comment: https://git.openjdk.org/jfx/pull/987#issuecomment-1493816574 From fkirmaier at openjdk.org Mon Apr 3 07:41:40 2023 From: fkirmaier at openjdk.org (Florian Kirmaier) Date: Mon, 3 Apr 2023 07:41:40 GMT Subject: RFR: 8273485: Deadlock when also using Swing and exiting Fullscreen on Mac [v9] In-Reply-To: References: Message-ID: On Mon, 18 Jul 2022 12:18:49 GMT, Florian Kirmaier wrote: >> When using Swing it's possible to generate a Deadlock. >> It's related to the nested eventloop started in enterFullScreenExitingLoop - and the RenderLock aquired when using setView in Scene. >> Sample Programm and Threaddump are added to the ticket. >> >> Removing the nested loop fixes the Problem. >> I hope this doesn't have any side effect - so far i don't know of any. > > Florian Kirmaier has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 10 commits: > > - JDK-8273485 > Fixing issue caused by wrong merge. > - Merge remote-tracking branch 'origin/master' into JDK-8273485_swing-deadlock > > # Conflicts: > # modules/javafx.graphics/src/main/native-glass/mac/GlassViewDelegate.m > - JDK-8273485 > Added check for null when calling initScreens > - JDK-8273485 > Fixing toggle fullscreen! > - JDK-8273485 > removed the toggle fullscreen before closing - to avoid the beep and improve the user experience > - JDK-8273485 > Fixed Beep sound when closing a fullscreen window > - JDK-8273485 > small cleanup of the changes. > - JDK-8273485 > Removed the enter/leave nested event loop logic, for mac fullscreen > - JDK-8273485 > Added unit-test > - JDK-8273485 > Fixing deadlock when switching to fullscreen, when also swing is used. I would like to keep this PR. I've worked weeks on it, to make this work. It's now been tested quite a long in production. I understand that this is hard to test. But It removes code, adds a unit test, fixes a reproducible bug, and has been used for a long time in a Real World application. That's usually the kind of PR we want to accept. ------------- PR Comment: https://git.openjdk.org/jfx/pull/622#issuecomment-1493829584 From jpereda at openjdk.org Mon Apr 3 08:19:27 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Mon, 3 Apr 2023 08:19:27 GMT Subject: RFR: JDK-8305248: TableView not rendered correctly after column is made visible if fixed cell size is set [v2] In-Reply-To: References: Message-ID: <-ZDaB43YjGPtraRO5gvS9X4Ju3SU48O09OvG3UHwYjE=.87c3099b-0591-4930-ac0c-980f8974d32a@github.com> On Sat, 1 Apr 2023 10:02:26 GMT, Marius Hanl wrote: >> The determined `prefWidth` of a `TableCell` could be `0.0` when a `fixedCellSize` is set. >> This happened because the `TableCell` may not have a skin since it was never added to the scene graph yet. >> >> The fix is to make sure we get the `prefWidth` after the `TableCell` was added to the scene graph. >> That is also the reason why the problem only happened the first time and never again after (skin is then already created). > > Marius Hanl has updated the pull request incrementally with two additional commits since the last revision: > > - JDK-8305248: Added the tests also for TreeTableRow > - JDK-8305248: Improve comments Looks good, I have just two minor comments. modules/javafx.controls/src/main/java/javafx/scene/control/skin/TableRowSkinBase.java line 356: > 354: getChildren().add(tableCell); > 355: } > 356: // Note: prefWidth() has to be called only after the tableCell is added to the tableRow, if it wasn't Minor: there is no explicit rule about limiting line comments to 80 characters, as far as I know, but it might be good to apply it to your comments (also to the test ones) modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/TreeTableRowSkinTest.java line 260: > 258: */ > 259: @Test > 260: public void testMakeInvisibleColumnVisible() { These two tests also pass with/without your patch, but I guess we want to have them to prevent any future issue? ------------- PR Review: https://git.openjdk.org/jfx/pull/1077#pullrequestreview-1368489198 PR Review Comment: https://git.openjdk.org/jfx/pull/1077#discussion_r1155611209 PR Review Comment: https://git.openjdk.org/jfx/pull/1077#discussion_r1155621366 From hmeda at openjdk.org Mon Apr 3 09:21:08 2023 From: hmeda at openjdk.org (Hima Bindu Meda) Date: Mon, 3 Apr 2023 09:21:08 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 [v3] In-Reply-To: References: Message-ID: > In Jenkins Build, the intermediate failure on windows is observed due to crash in mspdbserv.exe, which generates Program database (.pdb) files. > Disabled the pdb file generation in order to resolve the build failure. > Sanity testing looks fine. Verified build on windows, mac and linux. Hima Bindu Meda has updated the pull request incrementally with one additional commit since the last revision: remove white space ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1079/files - new: https://git.openjdk.org/jfx/pull/1079/files/d21b94a6..5b80745d Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1079&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1079&range=01-02 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1079.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1079/head:pull/1079 PR: https://git.openjdk.org/jfx/pull/1079 From mhanl at openjdk.org Mon Apr 3 09:34:05 2023 From: mhanl at openjdk.org (Marius Hanl) Date: Mon, 3 Apr 2023 09:34:05 GMT Subject: RFR: JDK-8305248: TableView not rendered correctly after column is made visible if fixed cell size is set [v2] In-Reply-To: <-ZDaB43YjGPtraRO5gvS9X4Ju3SU48O09OvG3UHwYjE=.87c3099b-0591-4930-ac0c-980f8974d32a@github.com> References: <-ZDaB43YjGPtraRO5gvS9X4Ju3SU48O09OvG3UHwYjE=.87c3099b-0591-4930-ac0c-980f8974d32a@github.com> Message-ID: <5G_op1pVH3Lo5GHa-XjIIvUW6R3m1w0hTf27AEYDVuk=.9d6e3d6f-91f4-443a-981b-731163d9d795@github.com> On Mon, 3 Apr 2023 08:00:50 GMT, Jose Pereda wrote: >> Marius Hanl has updated the pull request incrementally with two additional commits since the last revision: >> >> - JDK-8305248: Added the tests also for TreeTableRow >> - JDK-8305248: Improve comments > > modules/javafx.controls/src/main/java/javafx/scene/control/skin/TableRowSkinBase.java line 356: > >> 354: getChildren().add(tableCell); >> 355: } >> 356: // Note: prefWidth() has to be called only after the tableCell is added to the tableRow, if it wasn't > > Minor: there is no explicit rule about limiting line comments to 80 characters, as far as I know, but it might be good to apply it to your comments (also to the test ones) Actually there is! In https://github.com/openjdk/jfx/blob/master/CONTRIBUTING.md > Line width is no more than 120 character That is what I also use here and actually did in other PRs as well. If there is another rule I can of course change it, but a max line width of 120 is a reasonable value I saw in a lot of (Java) projects. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1077#discussion_r1155714498 From mhanl at openjdk.org Mon Apr 3 09:48:06 2023 From: mhanl at openjdk.org (Marius Hanl) Date: Mon, 3 Apr 2023 09:48:06 GMT Subject: RFR: JDK-8305248: TableView not rendered correctly after column is made visible if fixed cell size is set [v2] In-Reply-To: <-ZDaB43YjGPtraRO5gvS9X4Ju3SU48O09OvG3UHwYjE=.87c3099b-0591-4930-ac0c-980f8974d32a@github.com> References: <-ZDaB43YjGPtraRO5gvS9X4Ju3SU48O09OvG3UHwYjE=.87c3099b-0591-4930-ac0c-980f8974d32a@github.com> Message-ID: On Mon, 3 Apr 2023 08:10:04 GMT, Jose Pereda wrote: >> Marius Hanl has updated the pull request incrementally with two additional commits since the last revision: >> >> - JDK-8305248: Added the tests also for TreeTableRow >> - JDK-8305248: Improve comments > > modules/javafx.controls/src/test/java/test/javafx/scene/control/skin/TreeTableRowSkinTest.java line 260: > >> 258: */ >> 259: @Test >> 260: public void testMakeInvisibleColumnVisible() { > > These two tests also pass with/without your patch, but I guess we want to have them to prevent any future issue? Yes. `TreeTableView` does a lot more layout passes then `TableView`. I had a look on this in the past and in general the table implementations do too much (re)layouting unfortunately, and that sometimes masks bugs, like this one. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1077#discussion_r1155730499 From jpereda at openjdk.org Mon Apr 3 09:54:30 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Mon, 3 Apr 2023 09:54:30 GMT Subject: RFR: JDK-8305248: TableView not rendered correctly after column is made visible if fixed cell size is set [v2] In-Reply-To: <5G_op1pVH3Lo5GHa-XjIIvUW6R3m1w0hTf27AEYDVuk=.9d6e3d6f-91f4-443a-981b-731163d9d795@github.com> References: <-ZDaB43YjGPtraRO5gvS9X4Ju3SU48O09OvG3UHwYjE=.87c3099b-0591-4930-ac0c-980f8974d32a@github.com> <5G_op1pVH3Lo5GHa-XjIIvUW6R3m1w0hTf27AEYDVuk=.9d6e3d6f-91f4-443a-981b-731163d9d795@github.com> Message-ID: On Mon, 3 Apr 2023 09:31:15 GMT, Marius Hanl wrote: >> modules/javafx.controls/src/main/java/javafx/scene/control/skin/TableRowSkinBase.java line 356: >> >>> 354: getChildren().add(tableCell); >>> 355: } >>> 356: // Note: prefWidth() has to be called only after the tableCell is added to the tableRow, if it wasn't >> >> Minor: there is no explicit rule about limiting line comments to 80 characters, as far as I know, but it might be good to apply it to your comments (also to the test ones) > > Actually there is! In https://github.com/openjdk/jfx/blob/master/CONTRIBUTING.md >> Line width is no more than 120 character > > That is what I also use here and actually did in other PRs as well. > If there is another rule I can of course change it, but a max line width of 120 is a reasonable value I saw in a lot of other (Java) projects too. Ok, right, I missed that. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1077#discussion_r1155737810 From jpereda at openjdk.org Mon Apr 3 09:56:57 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Mon, 3 Apr 2023 09:56:57 GMT Subject: RFR: JDK-8305248: TableView not rendered correctly after column is made visible if fixed cell size is set [v2] In-Reply-To: References: Message-ID: On Sat, 1 Apr 2023 10:02:26 GMT, Marius Hanl wrote: >> The determined `prefWidth` of a `TableCell` could be `0.0` when a `fixedCellSize` is set. >> This happened because the `TableCell` may not have a skin since it was never added to the scene graph yet. >> >> The fix is to make sure we get the `prefWidth` after the `TableCell` was added to the scene graph. >> That is also the reason why the problem only happened the first time and never again after (skin is then already created). > > Marius Hanl has updated the pull request incrementally with two additional commits since the last revision: > > - JDK-8305248: Added the tests also for TreeTableRow > - JDK-8305248: Improve comments Looks good to me. The PR fixes the issue, a test fails before it and passes with it, and there are some more tests that, even without failing before this PR, are good to have to prevent future issues. ------------- Marked as reviewed by jpereda (Reviewer). PR Review: https://git.openjdk.org/jfx/pull/1077#pullrequestreview-1368690352 From thiago.sayao at gmail.com Mon Apr 3 11:32:43 2023 From: thiago.sayao at gmail.com (=?UTF-8?Q?Thiago_Milczarek_Say=C3=A3o?=) Date: Mon, 3 Apr 2023 08:32:43 -0300 Subject: Linux IME work In-Reply-To: References: Message-ID: I have submitted a Draft PR here: https://github.com/openjdk/jfx/pull/1080 It's not 100% right yet, I need some feedback to work on it. Em seg., 20 de mar. de 2023 ?s 09:50, Thiago Milczarek Say?o < thiago.sayao at gmail.com> escreveu: > Hi, > > I'm working on IME (Input Method Editor) on Linux as the current solution > using XIM is probably not working and XIM is known to be outdated. > > I'm basing it on > https://docs.gtk.org/gtk3/class.IMContext.html > > Which is built on top of Ibus (Intelligent Input Bus). To my understanding > there's an option for XIM too. > > I'm testing it using Japanese and Anthy. For now it's compiling and > sending IME commits to a TextArea but not deleting preedits (have to figure > it out how to do it). > > It's a land I started to explore (and I know nothing outside the > latin-based languages). I'm looking for use cases or samples I can use to > test. > > It's also a work to eliminate X11 calls so we can support wayland. > > Cheers > > > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kcr at openjdk.org Mon Apr 3 13:36:09 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 3 Apr 2023 13:36:09 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 In-Reply-To: <3lKGcPNGOyKZJv6UstI15xDgBR63gCKrng7Lp_k2Uy0=.6e812c60-43cd-4285-86dd-b31a0486ae15@github.com> References: <3lKGcPNGOyKZJv6UstI15xDgBR63gCKrng7Lp_k2Uy0=.6e812c60-43cd-4285-86dd-b31a0486ae15@github.com> Message-ID: On Sun, 2 Apr 2023 09:29:40 GMT, Johan Vos wrote: > do you have insight in why removing the debug flag "fixes" the problem? Are we sure that there is not something wrong below the surface that becomes visible in case The problem is triggered by the generation of the PDB files. PDB files are generated either when the `/Zi` flag is added at compile time or when the `/DEBUG` flag is added at link time. This PR removes both flags. As a follow-up, we should make sure that the PDB files are generated for DebugNative builds (which are currently broken). ------------- PR Comment: https://git.openjdk.org/jfx/pull/1079#issuecomment-1494333019 From kcr at openjdk.org Mon Apr 3 13:36:12 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 3 Apr 2023 13:36:12 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 [v3] In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 09:21:08 GMT, Hima Bindu Meda wrote: >> In Jenkins Build, the intermediate failure on windows is observed due to crash in mspdbserv.exe, which generates Program database (.pdb) files. >> Disabled the pdb file generation in order to resolve the build failure. >> Sanity testing looks fine. Verified build on windows, mac and linux. > > Hima Bindu Meda has updated the pull request incrementally with one additional commit since the last revision: > > remove white space modules/javafx.web/src/main/native/Source/cmake/OptionsMSVC.cmake line 114: > 112: if (NOT WTF_CPU_X86) > 113: if (PORT STREQUAL "Java") > 114: # Create pdb files for debugging purposes, also for Release builds Now that this is in an "if...Java" block, the comment is misleading. Maybe change it to something like "Suppress creation of pdb files for Release builds" and also add a "FIXME" or "TODO" to re-enable them for debug builds? ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1079#discussion_r1155961339 From kcr at openjdk.org Mon Apr 3 13:53:10 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 3 Apr 2023 13:53:10 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v4] In-Reply-To: References: Message-ID: On Sun, 2 Apr 2023 23:45:52 GMT, Michael Strau? wrote: >> modules/javafx.base/src/test/java/test/com/sun/javafx/collections/ObservableListWrapperTest.java line 41: >> >>> 39: >>> 40: @Nested >>> 41: class RemoveAllTest { >> >> Empty line after class declaration. >> >> Same for other places. > > I see that all over the JavaFX codebase. Do we have any guidance for that? We're inconsistent on this. Since this is a new class, I'd probably lean towards adding the blank line. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/751#discussion_r1155993184 From jgneff at openjdk.org Mon Apr 3 15:10:25 2023 From: jgneff at openjdk.org (John Neffenger) Date: Mon, 3 Apr 2023 15:10:25 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v11] In-Reply-To: References: Message-ID: <9eyuajF_WzfmnPbSkXngHbSD2aOtpnmvPfZsap_9De8=.9172c1e4-fd9a-489e-b414-7e3b14cdba4c@github.com> > This pull request allows for reproducible builds of JavaFX on Linux, macOS, and Windows by defining the `SOURCE_DATE_EPOCH` environment variable. For example, the following commands create a reproducible build: > > > $ export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) > $ bash gradlew sdk jmods javadoc > $ strip-nondeterminism -v -T $SOURCE_DATE_EPOCH build/jmods/*.jmod > > > The three commands: > > 1. set the build timestamp to the date of the latest source code change, > 2. build the JavaFX SDK libraries, JMOD archives, and API documentation, and > 3. recreate the JMOD files with stable file modification times and ordering. > > The third command won't be necessary once Gradle can build the JMOD archives or the `jmod` tool itself has the required support. For more information on the environment variable, see the [`SOURCE_DATE_EPOCH`][1] page. For more information on the command to recreate the JMOD files, see the [`strip-nondeterminism`][2] repository. I'd like to propose that we allow for reproducible builds in JavaFX 17 and consider making them the default in JavaFX 18. > > #### Fixes > > There are at least four sources of non-determinism in the JavaFX builds: > > 1. Build timestamp > > The class `com.sun.javafx.runtime.VersionInfo` in the JavaFX Base module stores the time of the build. Furthermore, for builds that don't run on the Hudson continuous integration tool, the class adds the build time to the system property `javafx.runtime.version`. > > 2. Modification times > > The JAR, JMOD, and ZIP archives store the modification time of each file. > > 3. File ordering > > The JAR, JMOD, and ZIP archives store their files in the order returned by the file system. The native shared libraries also store their object files in the order returned by the file system. Most file systems, though, do not guarantee the order of a directory's file listing. > > 4. Build path > > The class `com.sun.javafx.css.parser.Css2Bin` in the JavaFX Graphics module stores the absolute path of its `.css` input file in the corresponding `.bss` output file, which is then included in the JavaFX Controls module. > > This pull request modifies the Gradle and Groovy build files to fix the first three sources of non-determinism. A later pull request can modify the Java files to fix the fourth. > > [1]: https://reproducible-builds.org/docs/source-date-epoch/ > [2]: https://salsa.debian.org/reproducible-builds/strip-nondeterminism John Neffenger has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 20 commits: - Merge branch 'master' into allow-reproducible-builds - Support JDK 17 GA or later for building JavaFX - Merge branch 'master' into allow-reproducible-builds - Add '--date' argument for deterministic JMOD files - Merge branch 'master' into allow-reproducible-builds - Merge branch 'master' into allow-reproducible-builds - Comment out 'jmod --date' until building on JDK 19 Support for the 'jmod --date' option was added to JDK 19 starting with the 19+2 early-access build, and it was backported to JDK 17 starting with release 17.0.3. It is not available in JDK 18. - Merge 'master' into allow-reproducible-builds - Make minimal changes for new '--date' option - Add new '--date' option to JMOD task - ... and 10 more: https://git.openjdk.org/jfx/compare/c23d067d...1c4b4158 ------------- Changes: https://git.openjdk.org/jfx/pull/446/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=446&range=10 Stats: 147 lines in 7 files changed: 117 ins; 13 del; 17 mod Patch: https://git.openjdk.org/jfx/pull/446.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/446/head:pull/446 PR: https://git.openjdk.org/jfx/pull/446 From kcr at openjdk.org Mon Apr 3 15:20:45 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 3 Apr 2023 15:20:45 GMT Subject: RFR: 8260528: Clean glass-gtk sizing and positioning code [v56] In-Reply-To: References: <5-LHfl6_vdrmRjLivevBopnWBbzgO0ygK1dRPAFdzoM=.22e09b72-4142-4c1c-b320-94a1c48aaa69@github.com> Message-ID: On Sun, 2 Apr 2023 20:49:38 GMT, Thiago Milczarek Sayao wrote: >> This cleans size and positioning code, reducing special cases, code complexity and size. >> >> Changes: >> >> - cached extents: 28, 1, 1, 1 are old defaults - modern gnome uses different sizes. It does not assume any size because it varies - it does cache because it's unlikely to vary on the same system - but if it does occur, it will only waste a resize event. >> - window geometry, min/max size are centralized in `update_window_constraints`; >> - Frame extents (the window decoration size used for "total window size"): >> - frame extents are received in `process_property_notify`; >> - removed quirks in java code; >> - When received, call `set_bounds` again to adjust the size (to account decorations later received); >> - Removed `activate_window` because it's the same as focusing the window. `gtk_window_present` will deiconify and focus it. >> - `ensure_window_size` was a quirk - removed; >> - `requested_bounds` removed - not used anymore; >> - `window_configure` incorporated in `set_bounds` with `gtk_window_move` and `gtk_window_resize`; >> - `process_net_wm_property` is a work-around for Unity only (added a check if Unity - but it can probably be removed at some point) >> - `restack` split in `to_front()` and `to_back()` to conform to managed code; > > Thiago Milczarek Sayao has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 78 commits: > > - Merge branch 'master' into clean_glass_gtk > - Merge branch 'openjdk:master' into master > - Merge branch 'openjdk:master' into master > - Merge branch 'openjdk:master' into master > - Merge branch 'openjdk:master' into master > - Fix bug when window starts maximized and restores to wrong size > - Minor adjustments > - Fix window order > - Revert "Fix window order (focus event)" > > This reverts commit 1ab609906e48ed8fb1b6f229c3afc0d4d2b79472. > - Fix window order (focus event) > - ... and 68 more: https://git.openjdk.org/jfx/compare/c23d067d...89e4efc6 Marked as reviewed by kcr (Lead). ------------- PR Review: https://git.openjdk.org/jfx/pull/915#pullrequestreview-1369263586 From angorya at openjdk.org Mon Apr 3 15:32:17 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Mon, 3 Apr 2023 15:32:17 GMT Subject: RFR: JDK-8305248: TableView not rendered correctly after column is made visible if fixed cell size is set [v2] In-Reply-To: References: Message-ID: On Sat, 1 Apr 2023 10:02:26 GMT, Marius Hanl wrote: >> The determined `prefWidth` of a `TableCell` could be `0.0` when a `fixedCellSize` is set. >> This happened because the `TableCell` may not have a skin since it was never added to the scene graph yet. >> >> The fix is to make sure we get the `prefWidth` after the `TableCell` was added to the scene graph. >> That is also the reason why the problem only happened the first time and never again after (skin is then already created). > > Marius Hanl has updated the pull request incrementally with two additional commits since the last revision: > > - JDK-8305248: Added the tests also for TreeTableRow > - JDK-8305248: Improve comments looks good ------------- Marked as reviewed by angorya (Committer). PR Review: https://git.openjdk.org/jfx/pull/1077#pullrequestreview-1369282985 From jpereda at openjdk.org Mon Apr 3 16:22:16 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Mon, 3 Apr 2023 16:22:16 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: References: Message-ID: On Tue, 21 Mar 2023 22:49:34 GMT, Martin Fox wrote: >> This PR adds code to ensure that KeyCodeCombinations match KeyEvents as expected by more accurately mapping from a Mac key code to a Java key code based on the user?s active keyboard layout (the existing code assumes a US QWERTY layout). The new code first identifies a set of Mac keys which can produce different characters based on the user?s keyboard layout. A Mac key code outside that area is processed exactly as before. For a key inside the layout-sensitive area the code calls UCKeyTranslate to translate the key to an unshifted ASCII character based on the active keyboard and uses that to determine the Java key code. >> >> When performing the reverse mapping for the Robot the code first uses the old QWERTY mapping to find a candidate key. If it lies in the layout-sensitive area the code then scans the entire area calling UCKeyTranslate until it finds a match. If the key lies outside the layout-sensitive area it?s processed exactly as before. >> >> There are multiple duplicates of these bugs logged against Mac applications built with JavaFX. >> >> https://bugs.openjdk.java.net/browse/JDK-8090257 Mac: Inconsistent KeyEvents with alternative keyboard layouts >> https://bugs.openjdk.java.net/browse/JDK-8088120 [Accelerator, Mac] CMD + Z accelerator is not working with French keyboard >> https://bugs.openjdk.java.net/browse/JDK-8087915 Mac: accelerator doesn't take into account azerty keyboard layout >> https://bugs.openjdk.java.net/browse/JDK-8150709 Mac OSX and German Keyboard Layout (Y/Z) > > Martin Fox has updated the pull request incrementally with one additional commit since the last revision: > > Added manual cross-platform keyboard handling test tests/manual/events/KeyboardTest.java line 79: > 77: */ > 78: > 79: public class KeyboardTest extends Application { Could you clarify how to run the test and what one should expect? In my case, I'm running from Mac, with a Spanish physical keyboard, but changed to German keyboard from Keyboard -> Input sources -> German, and whether the Keyboard viewer is visible or not, I get: [Mac] Testing 78 keys on German without combinations Failed: code Numpad 0 did not produce any events ... Failed: code Decimal did not produce any events Tested 78 keys with 76 failures Is that expected? Is that test only meant for a German keyboard? ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1156181269 From andy.goryachev at oracle.com Mon Apr 3 16:47:09 2023 From: andy.goryachev at oracle.com (Andy Goryachev) Date: Mon, 3 Apr 2023 16:47:09 +0000 Subject: Gauging interest in bindings that can delay changing their value (debounce/throttle) In-Reply-To: References: Message-ID: My two cents: I think the functionality of debouncing should better be solved by a separate facility, rather than added to observables. An example would be a use case when multiple observables trigger an expensive or delayed computation or a UI update. Something along the lines of https://github.com/TomasMikula/ReactFX/blob/master/reactfx/src/main/java/org/reactfx/util/FxTimer.java or https://github.com/andy-goryachev/FxEditor/blob/master/src/goryachev/fx/FxTimer.java cheers, -andy From: openjfx-dev on behalf of Marius Hanl Date: Thursday, March 30, 2023 at 15:20 To: John Hendrikx Cc: openjfx-dev at openjdk.org Subject: Aw: Gauging interest in bindings that can delay changing their value (debounce/throttle) + 1 for this. Debouncing is a common functionality for observables. One of the common scenarios is obviously something like a search filter functionality, where typing in characters triggers an expensive calculation. Debouncing solves the problem by doing that when nothing happened for some time, which is typically met when the user finished typing. -- Marius Gesendet: Donnerstag, 23. M?rz 2023 um 18:09 Uhr Von: "John Hendrikx" An: openjfx-dev at openjdk.org Betreff: Gauging interest in bindings that can delay changing their value (debounce/throttle) Hi list, I've been working on a potential new API (and proof of concept implementation) for adding a new type of fluent binding which can delay changing their values, and I'm wondering how much interest there is in such a thing. The main purpose of such an API is to prevent being flooded with changes when properties change often, or to simply delay certain actions until the user has settled on a selection or has stopped typing. For this purpose I would like to introduce a default method on `ObservableValue` with the signature: ObservableValue throttle(Throttler throttler); The parameter `Throttler` can be obtained via static methods of a helper class named `FXThrottlers`. These provide various pre-configured throttlers that work correctly with JavaFX's event thread model. My current proof of concept provides: public static Throttler debounce(Duration quietPeriod); public static Throttler debounceTrailing(Duration quietPeriod); public static Throttler throttle(Duration period); public static Throttler throttleTrailing(Duration period); These are variations of similar concepts, and vary mostly in when exactly they will allow value changes; debouncers will wait for a period without any changes, while throttlers will periodically allow changes. The trailing variants will not immediately emit the first change but will wait for the period to elapse first; all variants will eventually take on the value of the source observable. Debouncing is typically used when you wish for an input to settle before taking action (like typing in a search bar), while throttling is used to give regular feedback but avoid doing so too often (like feedback during window resizing). Usage example which updates a preview panel when the user has finished (cursor) scrolling through a list view: ObjectProperty selectedItem = listView.getSelectionModel().selectedItemProperty(); selectedItem .throttle(FXThrottlers.debounceTrailing(Duration.ofMillis(500))) .addListener((obs, old, current) -> { if (current != null) { updatePreviewPanel(current); } }); Implementation details: ObservableValue is part of javafx.base, and as such can't use animations or call Platform::runLater. The ThrottledBinding implementation has abstracted all of these out into the Throttler class, and FXThrottlers (which would live in javafx.graphics) therefore provides the necessary call backs to integrate property changes correctly back onto the JavaFX event thread. The Throttler class also simplifies testing; the test can provide its own timing source and background scheduler. The Throttler interface has the following methods: /** * Schedules a command to run on an unspecified thread after the time * given by {@code nanos} elapses. * * @param command a command to run, cannot be {@code null} * @param nanos a time in nanoseconds */ void schedule(Runnable command, long nanos); /** * Provides the current time in nanoseconds. * * @return the current time in nanoseconds */ long nanoTime(); /** * Runs the given command as soon as possible on a thread specified by this * throttler for updating property values. * * @param command a command to run, cannot be {@code null} */ void update(Runnable command); /** * Given the current elapsed time in the current change window, and the * amount of time elapsed since the last change was detected, determines * if and by how much the current change window should be extended. * * @param elapsed nanoseconds elapsed since the start of the current change window * @param elapsedSinceLastChange nanoseconds elapsed since the last change * @return nanoseconds to extend the window with */ long determineInterval(long elapsed, long elapsedSinceLastChange); For testing purposes, the schedule and nanoTime can be provided such that the throttle function can be tested deterministically. For integrating with JavaFX, update is implemented as `Platform.runLater(command)`. The schedule and nanoTime methods delegate to an Executor and System.nanoTime respectively. When using properties without JavaFX, Throttler implementations can be provided which run property updates on a scheduler thread (just calling Runnable::run on the current thread) or via some user provided executor. A sample test case looks like this (read with a mono space font :-)): @Test void testThrottleLeadingAndTrailing() { // create Throttler with deterministic behavior: Throttler throttler = create(Throttler.IntervalHandler.throttle(Duration.ofNanos(4)); // create throttled observable: ObservableValue binding = source.throttle(throttler); assertChanges( binding, "--a-b--c---d-----e-------f-g-----------f-g-----", "--a---b---c---d---e------f---g---------f---g---" ); assertInvalidations( binding, "--a-b--c---d-----e-------f-g-----------f-g-----", "--i---i---i---i---i------i---i---------i---i---" ); } Thanks for reading, I look forward to your feedback! --John -------------- next part -------------- An HTML attachment was scrubbed... URL: From mhanl at openjdk.org Mon Apr 3 17:28:07 2023 From: mhanl at openjdk.org (Marius Hanl) Date: Mon, 3 Apr 2023 17:28:07 GMT Subject: Integrated: JDK-8305248: TableView not rendered correctly after column is made visible if fixed cell size is set In-Reply-To: References: Message-ID: <_seW-fNK_RLlOIJ6k9Qt7Tpw1qyg7S_V5ggDvaPMSPY=.7750f782-84b0-4db9-a073-65523e65c840@github.com> On Thu, 30 Mar 2023 19:58:31 GMT, Marius Hanl wrote: > The determined `prefWidth` of a `TableCell` could be `0.0` when a `fixedCellSize` is set. > This happened because the `TableCell` may not have a skin since it was never added to the scene graph yet. > > The fix is to make sure we get the `prefWidth` after the `TableCell` was added to the scene graph. > That is also the reason why the problem only happened the first time and never again after (skin is then already created). This pull request has now been integrated. Changeset: 4c0e0bd9 Author: Marius Hanl URL: https://git.openjdk.org/jfx/commit/4c0e0bd96adc02be721203193aed1d8676db9ebb Stats: 113 lines in 3 files changed: 104 ins; 6 del; 3 mod 8305248: TableView not rendered correctly after column is made visible if fixed cell size is set Reviewed-by: angorya, jpereda ------------- PR: https://git.openjdk.org/jfx/pull/1077 From kcr at openjdk.org Mon Apr 3 17:54:13 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 3 Apr 2023 17:54:13 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 [v3] In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 09:21:08 GMT, Hima Bindu Meda wrote: >> In Jenkins Build, the intermediate failure on windows is observed due to crash in mspdbserv.exe, which generates Program database (.pdb) files. >> Disabled the pdb file generation in order to resolve the build failure. >> Sanity testing looks fine. Verified build on windows, mac and linux. > > Hima Bindu Meda has updated the pull request incrementally with one additional commit since the last revision: > > remove white space Testing is green. I'll reapprove if you update the comment I suggested. ------------- Marked as reviewed by kcr (Lead). PR Review: https://git.openjdk.org/jfx/pull/1079#pullrequestreview-1369516640 From hmeda at openjdk.org Mon Apr 3 18:51:00 2023 From: hmeda at openjdk.org (Hima Bindu Meda) Date: Mon, 3 Apr 2023 18:51:00 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 [v3] In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 13:25:34 GMT, Kevin Rushforth wrote: >> Hima Bindu Meda has updated the pull request incrementally with one additional commit since the last revision: >> >> remove white space > > modules/javafx.web/src/main/native/Source/cmake/OptionsMSVC.cmake line 114: > >> 112: if (NOT WTF_CPU_X86) >> 113: if (PORT STREQUAL "Java") >> 114: # Create pdb files for debugging purposes, also for Release builds > > Now that this is in an "if...Java" block, the comment is misleading. Maybe change it to something like "Suppress creation of pdb files for Release builds" and also add a "FIXME" or "TODO" to re-enable them for debug builds? Done ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1079#discussion_r1156334650 From hmeda at openjdk.org Mon Apr 3 18:50:57 2023 From: hmeda at openjdk.org (Hima Bindu Meda) Date: Mon, 3 Apr 2023 18:50:57 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 [v4] In-Reply-To: References: Message-ID: > In Jenkins Build, the intermediate failure on windows is observed due to crash in mspdbserv.exe, which generates Program database (.pdb) files. > Disabled the pdb file generation in order to resolve the build failure. > Sanity testing looks fine. Verified build on windows, mac and linux. Hima Bindu Meda has updated the pull request incrementally with one additional commit since the last revision: Update proper comment ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1079/files - new: https://git.openjdk.org/jfx/pull/1079/files/5b80745d..166506ea Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1079&range=03 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1079&range=02-03 Stats: 2 lines in 1 file changed: 1 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1079.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1079/head:pull/1079 PR: https://git.openjdk.org/jfx/pull/1079 From john.hendrikx at gmail.com Mon Apr 3 19:05:33 2023 From: john.hendrikx at gmail.com (John Hendrikx) Date: Mon, 3 Apr 2023 21:05:33 +0200 Subject: Gauging interest in bindings that can delay changing their value (debounce/throttle) In-Reply-To: References: Message-ID: <74a7d082-91ee-8006-c680-4376cc70874e@gmail.com> Hi Andy, Those examples seem to be just timers, it would be hard to construct the primitives like throttle and debounce with these, as they don't take into account when the value last changed, or whether or not is important that the value changed again (reset timer or not).? These timers would just run forever, while the functionality I propose here would have no timers running when things are stable. The timeout would also trigger precisily on the first value change.? Having a running timer is more like sampling, not throttling or debouncing. The functionality I'm proposing would be more along the lines of #reduceSucessions in https://github.com/TomasMikula/ReactFX/blob/master/reactfx/src/main/java/org/reactfx/EventStream.java -- except that it would never support accumulation or combining of values (that's something for streams, not for values). --John On 03/04/2023 18:47, Andy Goryachev wrote: > > My two cents: I think the functionality of debouncing should better be > solved by a separate facility, rather than added to observables.? An > example would be a use case when multiple observables trigger an > expensive or delayed computation or a UI update. > > Something along the lines of > > https://github.com/TomasMikula/ReactFX/blob/master/reactfx/src/main/java/org/reactfx/util/FxTimer.java > > or > > https://github.com/andy-goryachev/FxEditor/blob/master/src/goryachev/fx/FxTimer.java > > cheers, > > -andy > > *From: *openjfx-dev on behalf of Marius > Hanl > *Date: *Thursday, March 30, 2023 at 15:20 > *To: *John Hendrikx > *Cc: *openjfx-dev at openjdk.org > *Subject: *Aw: Gauging interest in bindings that can delay changing > their value (debounce/throttle) > > + 1 for this. Debouncing is a common functionality for observables. > > One of the common scenarios is obviously something like a search > filter functionality, where typing in characters triggers an expensive > calculation. > > Debouncing solves the problem by doing that when nothing happened for > some time, which is typically met when the user finished typing. > > -- Marius > > *Gesendet:*?Donnerstag, 23. M?rz 2023 um 18:09 Uhr > *Von:*?"John Hendrikx" > *An:* openjfx-dev at openjdk.org > *Betreff:*?Gauging interest in bindings that can delay changing their > value (debounce/throttle) > > Hi list, > > I've been working on a potential new API (and proof of concept > implementation) for adding a new type of fluent binding which can delay > changing their values, and I'm wondering how much interest there is in > such a thing. > > The main purpose of such an API is to prevent being flooded with changes > when properties change often, or to simply delay certain actions until > the user has settled on a selection or has stopped typing. > > For this purpose I would like to introduce a default method on > `ObservableValue` with the signature: > > ??? ObservableValue throttle(Throttler throttler); > > The parameter `Throttler` can be obtained via static methods of a helper > class named `FXThrottlers`. These provide various pre-configured > throttlers that work correctly with JavaFX's event thread model.? My > current proof of concept provides: > > ??? public static Throttler debounce(Duration quietPeriod); > ??? public static Throttler debounceTrailing(Duration quietPeriod); > ??? public static Throttler throttle(Duration period); > ??? public static Throttler throttleTrailing(Duration period); > > These are variations of similar concepts, and vary mostly in when > exactly they will allow value changes; debouncers will wait for a period > without any changes, while throttlers will periodically allow changes. > The trailing variants will not immediately emit the first change but > will wait for the period to elapse first; all variants will eventually > take on the value of the source observable. Debouncing is typically > used when you wish for an input to settle before taking action (like > typing in a search bar), while throttling is used to give regular > feedback but avoid doing so too often (like feedback during window > resizing). > > Usage example which updates a preview panel when the user has finished > (cursor) scrolling through a list view: > > ??? ObjectProperty selectedItem = > listView.getSelectionModel().selectedItemProperty(); > > ??? selectedItem > .throttle(FXThrottlers.debounceTrailing(Duration.ofMillis(500))) > ??????? .addListener((obs, old, current) -> { > ???????????? if (current != null) { > ? ?? ??????????? updatePreviewPanel(current); > ???????????? } > ??????? }); > > Implementation details: > > ObservableValue is part of javafx.base, and as such can't use animations > or call Platform::runLater.? The ThrottledBinding implementation has > abstracted all of these out into the Throttler class, and FXThrottlers > (which would live in javafx.graphics) therefore provides the necessary > call backs to integrate property changes correctly back onto the JavaFX > event thread.? The Throttler class also simplifies testing; the test can > provide its own timing source and background scheduler.? The Throttler > interface has the following methods: > > ??? /** > ???? * Schedules a command to run on an unspecified thread after the time > ???? * given by {@code nanos} elapses. > ???? * > ???? * @param command a command to run, cannot be {@code null} > ???? * @param nanos a time in nanoseconds > ???? */ > ??? void schedule(Runnable command, long nanos); > > ??? /** > ???? * Provides the current time in nanoseconds. > ???? * > ???? * @return the current time in nanoseconds > ???? */ > ??? long nanoTime(); > > ??? /** > ???? * Runs the given command as soon as possible on a thread specified > by this > ???? * throttler for updating property values. > ???? * > ???? * @param command a command to run, cannot be {@code null} > ???? */ > ??? void update(Runnable command); > > ??? /** > ???? * Given the current elapsed time in the current change window, > and the > ???? * amount of time elapsed since the last change was detected, > determines > ???? * if and by how much the current change window should be extended. > ???? * > ???? * @param elapsed nanoseconds elapsed since the start of the > current change window > ???? * @param elapsedSinceLastChange nanoseconds elapsed since the last > change > ???? * @return nanoseconds to extend the window with > ???? */ > ??? long determineInterval(long elapsed, long elapsedSinceLastChange); > > For testing purposes, the schedule and nanoTime can be provided such > that the throttle function can be tested deterministically. For > integrating with JavaFX, update is implemented as > `Platform.runLater(command)`.? The schedule and nanoTime methods > delegate to an Executor and System.nanoTime respectively.? When using > properties without JavaFX, Throttler implementations can be provided > which run property updates on a scheduler thread (just calling > Runnable::run on the current thread) or via some user provided executor. > > A sample test case looks like this (read with a mono space font :-)): > > ??? @Test > ??? void testThrottleLeadingAndTrailing() { > ????? // create Throttler with deterministic behavior: > ????? Throttler throttler = > create(Throttler.IntervalHandler.throttle(Duration.ofNanos(4)); > > ????? // create throttled observable: > ????? ObservableValue binding = source.throttle(throttler); > > ????? assertChanges( > ??????? binding, > "--a-b--c---d-----e-------f-g-----------f-g-----", > "--a---b---c---d---e------f---g---------f---g---" > ????? ); > > ????? assertInvalidations( > ??????? binding, > "--a-b--c---d-----e-------f-g-----------f-g-----", > "--i---i---i---i---i------i---i---------i---i---" > ????? ); > ??? } > > Thanks for reading, I look forward to your feedback! > > --John > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From andy.goryachev at oracle.com Mon Apr 3 19:14:46 2023 From: andy.goryachev at oracle.com (Andy Goryachev) Date: Mon, 3 Apr 2023 19:14:46 +0000 Subject: [External] : Re: Gauging interest in bindings that can delay changing their value (debounce/throttle) In-Reply-To: <74a7d082-91ee-8006-c680-4376cc70874e@gmail.com> References: <74a7d082-91ee-8006-c680-4376cc70874e@gmail.com> Message-ID: Right. I am not saying we should take these classes as is. In my opinion, this functionality might be better supported by a separate facility(ies). Specifically, to handle the case of multiple observables. I also think the APIs are large and complicated enough already, it might be better to add/extract (a rarely used) functionality to a separate class or set of classes. -andy From: John Hendrikx Date: Monday, April 3, 2023 at 12:05 To: Andy Goryachev , Marius Hanl Cc: openjfx-dev at openjdk.org Subject: [External] : Re: Gauging interest in bindings that can delay changing their value (debounce/throttle) Hi Andy, Those examples seem to be just timers, it would be hard to construct the primitives like throttle and debounce with these, as they don't take into account when the value last changed, or whether or not is important that the value changed again (reset timer or not). These timers would just run forever, while the functionality I propose here would have no timers running when things are stable. The timeout would also trigger precisily on the first value change. Having a running timer is more like sampling, not throttling or debouncing. The functionality I'm proposing would be more along the lines of #reduceSucessions in https://github.com/TomasMikula/ReactFX/blob/master/reactfx/src/main/java/org/reactfx/EventStream.java -- except that it would never support accumulation or combining of values (that's something for streams, not for values). --John On 03/04/2023 18:47, Andy Goryachev wrote: My two cents: I think the functionality of debouncing should better be solved by a separate facility, rather than added to observables. An example would be a use case when multiple observables trigger an expensive or delayed computation or a UI update. Something along the lines of https://github.com/TomasMikula/ReactFX/blob/master/reactfx/src/main/java/org/reactfx/util/FxTimer.java or https://github.com/andy-goryachev/FxEditor/blob/master/src/goryachev/fx/FxTimer.java cheers, -andy From: openjfx-dev on behalf of Marius Hanl Date: Thursday, March 30, 2023 at 15:20 To: John Hendrikx Cc: openjfx-dev at openjdk.org Subject: Aw: Gauging interest in bindings that can delay changing their value (debounce/throttle) + 1 for this. Debouncing is a common functionality for observables. One of the common scenarios is obviously something like a search filter functionality, where typing in characters triggers an expensive calculation. Debouncing solves the problem by doing that when nothing happened for some time, which is typically met when the user finished typing. -- Marius Gesendet: Donnerstag, 23. M?rz 2023 um 18:09 Uhr Von: "John Hendrikx" An: openjfx-dev at openjdk.org Betreff: Gauging interest in bindings that can delay changing their value (debounce/throttle) Hi list, I've been working on a potential new API (and proof of concept implementation) for adding a new type of fluent binding which can delay changing their values, and I'm wondering how much interest there is in such a thing. The main purpose of such an API is to prevent being flooded with changes when properties change often, or to simply delay certain actions until the user has settled on a selection or has stopped typing. For this purpose I would like to introduce a default method on `ObservableValue` with the signature: ObservableValue throttle(Throttler throttler); The parameter `Throttler` can be obtained via static methods of a helper class named `FXThrottlers`. These provide various pre-configured throttlers that work correctly with JavaFX's event thread model. My current proof of concept provides: public static Throttler debounce(Duration quietPeriod); public static Throttler debounceTrailing(Duration quietPeriod); public static Throttler throttle(Duration period); public static Throttler throttleTrailing(Duration period); These are variations of similar concepts, and vary mostly in when exactly they will allow value changes; debouncers will wait for a period without any changes, while throttlers will periodically allow changes. The trailing variants will not immediately emit the first change but will wait for the period to elapse first; all variants will eventually take on the value of the source observable. Debouncing is typically used when you wish for an input to settle before taking action (like typing in a search bar), while throttling is used to give regular feedback but avoid doing so too often (like feedback during window resizing). Usage example which updates a preview panel when the user has finished (cursor) scrolling through a list view: ObjectProperty selectedItem = listView.getSelectionModel().selectedItemProperty(); selectedItem .throttle(FXThrottlers.debounceTrailing(Duration.ofMillis(500))) .addListener((obs, old, current) -> { if (current != null) { updatePreviewPanel(current); } }); Implementation details: ObservableValue is part of javafx.base, and as such can't use animations or call Platform::runLater. The ThrottledBinding implementation has abstracted all of these out into the Throttler class, and FXThrottlers (which would live in javafx.graphics) therefore provides the necessary call backs to integrate property changes correctly back onto the JavaFX event thread. The Throttler class also simplifies testing; the test can provide its own timing source and background scheduler. The Throttler interface has the following methods: /** * Schedules a command to run on an unspecified thread after the time * given by {@code nanos} elapses. * * @param command a command to run, cannot be {@code null} * @param nanos a time in nanoseconds */ void schedule(Runnable command, long nanos); /** * Provides the current time in nanoseconds. * * @return the current time in nanoseconds */ long nanoTime(); /** * Runs the given command as soon as possible on a thread specified by this * throttler for updating property values. * * @param command a command to run, cannot be {@code null} */ void update(Runnable command); /** * Given the current elapsed time in the current change window, and the * amount of time elapsed since the last change was detected, determines * if and by how much the current change window should be extended. * * @param elapsed nanoseconds elapsed since the start of the current change window * @param elapsedSinceLastChange nanoseconds elapsed since the last change * @return nanoseconds to extend the window with */ long determineInterval(long elapsed, long elapsedSinceLastChange); For testing purposes, the schedule and nanoTime can be provided such that the throttle function can be tested deterministically. For integrating with JavaFX, update is implemented as `Platform.runLater(command)`. The schedule and nanoTime methods delegate to an Executor and System.nanoTime respectively. When using properties without JavaFX, Throttler implementations can be provided which run property updates on a scheduler thread (just calling Runnable::run on the current thread) or via some user provided executor. A sample test case looks like this (read with a mono space font :-)): @Test void testThrottleLeadingAndTrailing() { // create Throttler with deterministic behavior: Throttler throttler = create(Throttler.IntervalHandler.throttle(Duration.ofNanos(4)); // create throttled observable: ObservableValue binding = source.throttle(throttler); assertChanges( binding, "--a-b--c---d-----e-------f-g-----------f-g-----", "--a---b---c---d---e------f---g---------f---g---" ); assertInvalidations( binding, "--a-b--c---d-----e-------f-g-----------f-g-----", "--i---i---i---i---i------i---i---------i---i---" ); } Thanks for reading, I look forward to your feedback! --John -------------- next part -------------- An HTML attachment was scrubbed... URL: From kcr at openjdk.org Mon Apr 3 19:26:10 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 3 Apr 2023 19:26:10 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 [v4] In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 18:50:57 GMT, Hima Bindu Meda wrote: >> In Jenkins Build, the intermediate failure on windows is observed due to crash in mspdbserv.exe, which generates Program database (.pdb) files. >> Disabled the pdb file generation in order to resolve the build failure. >> Sanity testing looks fine. Verified build on windows, mac and linux. > > Hima Bindu Meda has updated the pull request incrementally with one additional commit since the last revision: > > Update proper comment Marked as reviewed by kcr (Lead). ------------- PR Review: https://git.openjdk.org/jfx/pull/1079#pullrequestreview-1369661584 From mhanl at openjdk.org Mon Apr 3 20:04:19 2023 From: mhanl at openjdk.org (Marius Hanl) Date: Mon, 3 Apr 2023 20:04:19 GMT Subject: RFR: 8223373: Remove IntelliJ IDEA specific files from the source code repository [v5] In-Reply-To: <3zCUdkkbxcB1NMO9-VFrOgALNGa4k2vC0yXoyqYSbyQ=.596e4f9c-9101-4548-9d7e-134f06d1770c@github.com> References: <3zCUdkkbxcB1NMO9-VFrOgALNGa4k2vC0yXoyqYSbyQ=.596e4f9c-9101-4548-9d7e-134f06d1770c@github.com> Message-ID: On Fri, 3 Mar 2023 01:13:49 GMT, Thiago Milczarek Sayao wrote: >> This PR does: >> >> - Remove specific Idea files and let it be imported from gradle; >> - Adds checkstyle (to use with checkstyle plugin - it will let you know style mistakes); >> - Configures auto-format to sun style (with the changes mentioned in [Code Style Rules](https://wiki.openjdk.org/display/OpenJFX/Code+Style+Rules)); >> - Automatically sets Copyright notice (updates year too); >> - Run configurations for samples/toys and builds. > > Thiago Milczarek Sayao has updated the pull request incrementally with two additional commits since the last revision: > > - Revert "Make intellij see :systemTests dependecies" > > This reverts commit dca7eab24958e1214147b7d291f0faf52ea27ddf. > - Make intellij see :systemTests dependecies LGTM, tested successfully on my Windows machine with IntelliJ. ------------- Marked as reviewed by mhanl (Committer). PR Review: https://git.openjdk.org/jfx/pull/1009#pullrequestreview-1369719014 From john.hendrikx at gmail.com Mon Apr 3 21:46:21 2023 From: john.hendrikx at gmail.com (John Hendrikx) Date: Mon, 3 Apr 2023 23:46:21 +0200 Subject: [External] : Re: Gauging interest in bindings that can delay changing their value (debounce/throttle) In-Reply-To: References: <74a7d082-91ee-8006-c680-4376cc70874e@gmail.com> Message-ID: <388e5e7b-c757-1034-c617-4df8ab674335@gmail.com> Hi Andy, On 03/04/2023 21:14, Andy Goryachev wrote: > > Right. I am not saying we should take these classes as is. > > In my opinion, this functionality might be better supported by a > separate facility(ies).? Specifically, to handle the case of multiple > observables. > Can you elaborate on what cases you see with multiple observables?? I think you mean events here; events can also benefit from debouncing or throttling, but that's something quite different.? An ObservableValue is not an event source, but the values it takes on can be mapped, delayed or even interpolated. In the end however, there is always a value immediately available, making them suitable for binding.? An event source on the other hand can't supply events (values) on demand, can't repeat them and it does not remember the last one -- you can't bind an event source in the same way either; at the most you can set a default value and then update it when events come in. > I also think the APIs are large and complicated enough already, it > might be better to add/extract (a rarely used) functionality to a > separate class or set of classes. > Could you clarify at what point an API is too large or too complicated? Certainly there are far larger API's in the Java ecosystem and in the JDK itself.? I'm pretty sure there are far more complicated ones as well. --John > -andy > > *From: *John Hendrikx > *Date: *Monday, April 3, 2023 at 12:05 > *To: *Andy Goryachev , Marius Hanl > > *Cc: *openjfx-dev at openjdk.org > *Subject: *[External] : Re: Gauging interest in bindings that can > delay changing their value (debounce/throttle) > > Hi Andy, > > Those examples seem to be just timers, it would be hard to construct > the primitives like throttle and debounce with these, as they don't > take into account when the value last changed, or whether or not is > important that the value changed again (reset timer or not).? These > timers would just run forever, while the functionality I propose here > would have no timers running when things are stable. The timeout would > also trigger precisily on the first value change.? Having a running > timer is more like sampling, not throttling or debouncing. > > The functionality I'm proposing would be more along the lines of > #reduceSucessions in > https://github.com/TomasMikula/ReactFX/blob/master/reactfx/src/main/java/org/reactfx/EventStream.java > > -- except that it would never support accumulation or combining of > values (that's something for streams, not for values). > > --John > > On 03/04/2023 18:47, Andy Goryachev wrote: > > My two cents: I think the functionality of debouncing should > better be solved by a separate facility, rather than added to > observables.? An example would be a use case when multiple > observables trigger an expensive or delayed computation or a UI > update. > > Something along the lines of > > https://github.com/TomasMikula/ReactFX/blob/master/reactfx/src/main/java/org/reactfx/util/FxTimer.java > > > or > > https://github.com/andy-goryachev/FxEditor/blob/master/src/goryachev/fx/FxTimer.java > > > cheers, > > -andy > > *From: *openjfx-dev > on behalf of Marius Hanl > > *Date: *Thursday, March 30, 2023 at 15:20 > *To: *John Hendrikx > > *Cc: *openjfx-dev at openjdk.org > > *Subject: *Aw: Gauging interest in bindings that can delay > changing their value (debounce/throttle) > > + 1 for this. Debouncing is a common functionality for observables. > > One of the common scenarios is obviously something like a search > filter functionality, where typing in characters triggers an > expensive calculation. > > Debouncing solves the problem by doing that when nothing happened > for some time, which is typically met when the user finished typing. > > -- Marius > > *Gesendet:*?Donnerstag, 23. M?rz 2023 um 18:09 Uhr > *Von:*?"John Hendrikx" > > *An:* openjfx-dev at openjdk.org > *Betreff:*?Gauging interest in bindings that can delay changing > their value (debounce/throttle) > > Hi list, > > I've been working on a potential new API (and proof of concept > implementation) for adding a new type of fluent binding which can > delay > changing their values, and I'm wondering how much interest there is in > such a thing. > > The main purpose of such an API is to prevent being flooded with > changes > when properties change often, or to simply delay certain actions until > the user has settled on a selection or has stopped typing. > > For this purpose I would like to introduce a default method on > `ObservableValue` with the signature: > > ??? ObservableValue throttle(Throttler throttler); > > The parameter `Throttler` can be obtained via static methods of a > helper > class named `FXThrottlers`. These provide various pre-configured > throttlers that work correctly with JavaFX's event thread model.? My > current proof of concept provides: > > ??? public static Throttler debounce(Duration quietPeriod); > ??? public static Throttler debounceTrailing(Duration quietPeriod); > ??? public static Throttler throttle(Duration period); > ??? public static Throttler throttleTrailing(Duration period); > > These are variations of similar concepts, and vary mostly in when > exactly they will allow value changes; debouncers will wait for a > period > without any changes, while throttlers will periodically allow changes. > The trailing variants will not immediately emit the first change but > will wait for the period to elapse first; all variants will eventually > take on the value of the source observable. Debouncing is typically > used when you wish for an input to settle before taking action (like > typing in a search bar), while throttling is used to give regular > feedback but avoid doing so too often (like feedback during window > resizing). > > Usage example which updates a preview panel when the user has finished > (cursor) scrolling through a list view: > > ??? ObjectProperty selectedItem = > listView.getSelectionModel().selectedItemProperty(); > > ??? selectedItem > .throttle(FXThrottlers.debounceTrailing(Duration.ofMillis(500))) > ??????? .addListener((obs, old, current) -> { > ???????????? if (current != null) { > ? ?? ??????????? updatePreviewPanel(current); > ???????????? } > ??????? }); > > Implementation details: > > ObservableValue is part of javafx.base, and as such can't use > animations > or call Platform::runLater.? The ThrottledBinding implementation has > abstracted all of these out into the Throttler class, and FXThrottlers > (which would live in javafx.graphics) therefore provides the necessary > call backs to integrate property changes correctly back onto the > JavaFX > event thread.? The Throttler class also simplifies testing; the > test can > provide its own timing source and background scheduler.? The Throttler > interface has the following methods: > > ??? /** > ???? * Schedules a command to run on an unspecified thread after > the time > ???? * given by {@code nanos} elapses. > ???? * > ???? * @param command a command to run, cannot be {@code null} > ???? * @param nanos a time in nanoseconds > ???? */ > ??? void schedule(Runnable command, long nanos); > > ??? /** > ???? * Provides the current time in nanoseconds. > ???? * > ???? * @return the current time in nanoseconds > ???? */ > ??? long nanoTime(); > > ??? /** > ???? * Runs the given command as soon as possible on a thread > specified > by this > ???? * throttler for updating property values. > ???? * > ???? * @param command a command to run, cannot be {@code null} > ???? */ > ??? void update(Runnable command); > > ??? /** > ???? * Given the current elapsed time in the current change > window, and the > ???? * amount of time elapsed since the last change was detected, > determines > ???? * if and by how much the current change window should be > extended. > ???? * > ???? * @param elapsed nanoseconds elapsed since the start of the > current change window > ???? * @param elapsedSinceLastChange nanoseconds elapsed since the > last > change > ???? * @return nanoseconds to extend the window with > ???? */ > ??? long determineInterval(long elapsed, long elapsedSinceLastChange); > > For testing purposes, the schedule and nanoTime can be provided such > that the throttle function can be tested deterministically. For > integrating with JavaFX, update is implemented as > `Platform.runLater(command)`.? The schedule and nanoTime methods > delegate to an Executor and System.nanoTime respectively.? When using > properties without JavaFX, Throttler implementations can be provided > which run property updates on a scheduler thread (just calling > Runnable::run on the current thread) or via some user provided > executor. > > A sample test case looks like this (read with a mono space font :-)): > > ??? @Test > ??? void testThrottleLeadingAndTrailing() { > ????? // create Throttler with deterministic behavior: > ????? Throttler throttler = > create(Throttler.IntervalHandler.throttle(Duration.ofNanos(4)); > > ????? // create throttled observable: > ????? ObservableValue binding = source.throttle(throttler); > > ????? assertChanges( > ??????? binding, > "--a-b--c---d-----e-------f-g-----------f-g-----", > "--a---b---c---d---e------f---g---------f---g---" > ????? ); > > ????? assertInvalidations( > ??????? binding, > "--a-b--c---d-----e-------f-g-----------f-g-----", > "--i---i---i---i---i------i---i---------i---i---" > ????? ); > ??? } > > Thanks for reading, I look forward to your feedback! > > --John > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From prr at openjdk.org Mon Apr 3 21:50:13 2023 From: prr at openjdk.org (Phil Race) Date: Mon, 3 Apr 2023 21:50:13 GMT Subject: RFR: 8304441: [macos] Crash when putting invalid unicode char on clipboard In-Reply-To: <6AADnJNah6umVMFeVYodgaBdDoVnDj5UicoE6IST0Kk=.a63ed42d-16ad-4901-aa8b-3f5fac9f64ea@github.com> References: <6AADnJNah6umVMFeVYodgaBdDoVnDj5UicoE6IST0Kk=.a63ed42d-16ad-4901-aa8b-3f5fac9f64ea@github.com> Message-ID: On Tue, 28 Mar 2023 15:09:29 GMT, Kevin Rushforth wrote: > A malformed unicode string containing only half of a surrogate pair (either a high or low surrogate without the other half) will cause a native exception in the macOS `NSPasteboardItem setString:forType:` method. This uncaught exception will terminate (crash) the application. > > The fix is to validate the string before calling `setString:forType:`. I also added a try / catch that logs a warning, so that if we ever run into other exceptions, they won't be fatal. > > I added an automated test that fails on macOS without the fix and passes with the fix. The test is run on other platforms as well, and passes both before and after the fix. lgtm ------------- Marked as reviewed by prr (Reviewer). PR Review: https://git.openjdk.org/jfx/pull/1074#pullrequestreview-1369843759 From prr at openjdk.org Mon Apr 3 22:34:17 2023 From: prr at openjdk.org (Phil Race) Date: Mon, 3 Apr 2023 22:34:17 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS Message-ID: This PR addresses some font problems on macOS. (1) Garbled Arabic with the System font (2) Non-ideal fallback fonts for all fonts (3) No bold for System font. In particular the standard System Font was garbling Arabic text - random glyphs from another font. The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract the name from the core text font loaded by that special API. These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" and "SFArabic.ttf" and similar. JavaFX has its own "System" font family logical name and in order to map to the macOS system font, several releases ago we started using the special API referenced above. Normally we have our own list of fall back fonts for other scripts. But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds this new font to its fallback list - by name. But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. So to fix this we need to grab the reference to the font that was returned by CoreText and use that to create the PrismFont we add as a fall back. The code that first recognises it needs to go this route is in CTGlyphLayout.java when "getSlotForFont(String name") fails. Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. There's also supporting changes in native code - coretext.c Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, we need to make some more changes Now on to more "fallback" enhancements. Prior to this fix, on macOS we had a short, hard-coded global list. This fix calls the macOS API to get the cascading fallback list for a font. This improves the fallback behaviour in respect to providing (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from "if else if else in shared code, down into the appropriate platform factory This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes were made to follow it. In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" file name. Without being able to identify the file we aren't able to use the font to skip them. More changes would be needed to provide a PrismFont subclass that can handle this case. Fortunately that isn't happening for any of the fallbacks we get from complex text layout. The final thing this fixes is that "System Bold" was the same as "System Regular". The needed name getting lost along the way to constructing the native font. The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. And some day after that we could expose API that allows apps to request non-named variations. ------------- Commit messages: - fix bold detection - Remove more trailing whitespace - Remove trailing whitespace - Remove commented line - Update windows JNI names - Merge branch 'master' of github.com:prrace/jfx into arabic_etc - Fix bold italic - 8246104 Changes: https://git.openjdk.org/jfx/pull/1067/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8246104 Stats: 877 lines in 20 files changed: 652 ins; 155 del; 70 mod Patch: https://git.openjdk.org/jfx/pull/1067.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1067/head:pull/1067 PR: https://git.openjdk.org/jfx/pull/1067 From angorya at openjdk.org Mon Apr 3 22:34:18 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Mon, 3 Apr 2023 22:34:18 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Fri, 24 Mar 2023 21:37:16 GMT, Phil Race wrote: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. For completeness sake, here are the results of my testing as of 3/24: fixed scripts: Bagri Burmese Dhundhari Farsi Ge'ez Gujarati Hebrew Inuktitut Kannada Malvi Mevari Punjabi Pahari Suret Thaana Turoyo Urdu scripts still missing: Akkadian Bhojpuri Magahi Meitei Santali Thai miscellaneous notes: - Tulu seems to have issues rendering combining characters (at least that's how it looks to me) in both old and new code - italic is rendered as bold ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1485500068 From kcr at openjdk.org Mon Apr 3 22:34:19 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 3 Apr 2023 22:34:19 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Fri, 24 Mar 2023 21:37:16 GMT, Phil Race wrote: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. @johanvos You might want to take a look at this, since it supersedes your earlier PR #547. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1495070346 From prr at openjdk.org Mon Apr 3 22:42:16 2023 From: prr at openjdk.org (Phil Race) Date: Mon, 3 Apr 2023 22:42:16 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Mon, 27 Mar 2023 16:56:16 GMT, Andy Goryachev wrote: > * italic is rendered as bold That was in the draft PR and I said a known issue to ignore. It is already resolved. The missing scripts are because macOS isn't enumerating supplemental fonts that support them as fallbacks. That's a topic for another day. You mention "Thai" amongst them .. but I do see Thai rendered .. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1495078139 From john.hendrikx at gmail.com Mon Apr 3 22:51:22 2023 From: john.hendrikx at gmail.com (John Hendrikx) Date: Tue, 4 Apr 2023 00:51:22 +0200 Subject: Non-final fireValueChangedEvent in PropertyBase classes an unfortunate design decision? Message-ID: <07ea5577-99ab-5bcd-93be-ed520c4c4982@gmail.com> I have some observations about the method `fireValueChangedEvent` that most PropertyBase classes provide. They seem to have several design problems: 1) It's specified that it is called internally when `set` is called (dangerous, as it can be overriden and not do anything breaking the contract of the PropertyBase classes). 2) When overridden, it does the exact same thing as `invalidated` (they're always called at the exact same time) -- perhaps `invalidated` was a later addition? 3) When called externally, it can trigger invalidation listeners over and over; there is no check if the property was actually valid.? It just fires all listeners ignoring the normal constraints.? Notifying invalidation listeners again when already invalid is the use case they were designed to avoid. My problem with this implementation is primarily in the fact that the implementations of the PropertyBase classes are **forced** to call it internally, as otherwise classes which override this method would "miss" this "event".? But that isn't the only issue; I could just leave the implementation empty and call both that method and another method that does what I want, but that runs into a different problem: if I leave the implementation empty, then legitimate external calls of `fireValueChangedEvent` would become no-ops. So, I can't change the implementation because then it doesn't do anymore what external parties expect, and I can't **not** call it because then overriders wouldn't be informed of the change. The reason this is bothering me is because I see a way to optimize memory use for all properties that have a change listener attached, but I can't make the change because the Base classes have exposed some unfortunate internals.? The optimization is simple; a property has its value, but so does ExpressionHelper, it has a copy -- they both have the "current" value of the property. It would be trivially easy to supply the ExpressionHelper with the old value by saving this value off just before changing the property's value, and then supplying it when calling `ExpressionHelper#fireValueChangedEvent`... except for this one little snag where I'm forced to call `ObjectPropertyBase#fireValueChangedEvent` of which I can't change the implementation... Unfortunately, I don't think there is a way to solve this, so we're stuck with having to store the current value of a property in two places.? In theory, the `fireValueChangedEvent` method could be made final, and any code that overrides it could override `invalidated` instead.? In that case, internal calls could go via a different route allowing for supplying an old value when its value was set directly, while external callers can still use the existing method (which will use the current value as its old value, and preferably, also avoids calling invalidation listeners when not needed). --John From angorya at openjdk.org Mon Apr 3 22:57:52 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Mon, 3 Apr 2023 22:57:52 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 22:39:24 GMT, Phil Race wrote: > You mention "Thai" amongst them .. but I do see Thai rendered .. Thai is not rendered for me, was Ventura 13.1, now Ventura 13.3 on Mac M1, (left - ventura 13.1 with the earlier commit, right - unpatched master) ![Screenshot 2023-03-24 at 15 05 46](https://user-images.githubusercontent.com/107069028/229644057-dda227e1-9ead-4d62-ba20-d1192891ccc5.png) ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1495088913 From duke at openjdk.org Mon Apr 3 22:58:00 2023 From: duke at openjdk.org (Martin Fox) Date: Mon, 3 Apr 2023 22:58:00 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 16:19:47 GMT, Jose Pereda wrote: >> Martin Fox has updated the pull request incrementally with one additional commit since the last revision: >> >> Added manual cross-platform keyboard handling test > > tests/manual/events/KeyboardTest.java line 79: > >> 77: */ >> 78: >> 79: public class KeyboardTest extends Application { > > Could you clarify how to run the test and what one should expect? > > In my case, I'm running from Mac, with a Spanish physical keyboard, but changed to German keyboard from Keyboard -> Input sources -> German, and whether the Keyboard viewer is visible or not, I get: > > [Mac] Testing 78 keys on German without combinations > Failed: code Numpad 0 did not produce any events > ... > Failed: code Decimal did not produce any events > Tested 78 keys with 76 failures > > Is that expected? Is that test only meant for a German keyboard? @jperedadnr You set up the test correctly. I think you need to need to allow the 'terminal' application to use the accessibility API so the Java robot can send keyboard events. I can't provide you with the exact setting since I'm away from my Mac until the end of this week. When I get back I'll send details and add a comment to the test file. Apologies, I set up my Mac so long ago I forgot about this hiccup. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1156524005 From andy.goryachev at oracle.com Mon Apr 3 22:59:38 2023 From: andy.goryachev at oracle.com (Andy Goryachev) Date: Mon, 3 Apr 2023 22:59:38 +0000 Subject: [External] : Re: Gauging interest in bindings that can delay changing their value (debounce/throttle) In-Reply-To: <388e5e7b-c757-1034-c617-4df8ab674335@gmail.com> References: <74a7d082-91ee-8006-c680-4376cc70874e@gmail.com> <388e5e7b-c757-1034-c617-4df8ab674335@gmail.com> Message-ID: The use cases I have in mind are: - have a form with multiple fields. some kind of processing is supposed to be happen after a short delay after one or more fields is modified by the user - multiple fields are modified in rapid succession (programmatically). something must be invoked once after a short delay. There is another use case for throttling - for example, last price of a security in a trading application - but it may or may not be a good example because it would likely to be handled by a non-FX code first and then the actual property would be updated in an invokeLater(). Perhaps there are some use cases that I don't see that warrant the use of the new methods being proposed. What are those, and why do we need to them to an already large API surface instead of implementing a separate facility? Thanks! -andy From: John Hendrikx Date: Monday, April 3, 2023 at 14:46 To: Andy Goryachev , Marius Hanl Cc: openjfx-dev at openjdk.org Subject: Re: [External] : Re: Gauging interest in bindings that can delay changing their value (debounce/throttle) Hi Andy, On 03/04/2023 21:14, Andy Goryachev wrote: Right. I am not saying we should take these classes as is. In my opinion, this functionality might be better supported by a separate facility(ies). Specifically, to handle the case of multiple observables. Can you elaborate on what cases you see with multiple observables? I think you mean events here; events can also benefit from debouncing or throttling, but that's something quite different. An ObservableValue is not an event source, but the values it takes on can be mapped, delayed or even interpolated. In the end however, there is always a value immediately available, making them suitable for binding. An event source on the other hand can't supply events (values) on demand, can't repeat them and it does not remember the last one -- you can't bind an event source in the same way either; at the most you can set a default value and then update it when events come in. I also think the APIs are large and complicated enough already, it might be better to add/extract (a rarely used) functionality to a separate class or set of classes. Could you clarify at what point an API is too large or too complicated? Certainly there are far larger API's in the Java ecosystem and in the JDK itself. I'm pretty sure there are far more complicated ones as well. --John -andy From: John Hendrikx Date: Monday, April 3, 2023 at 12:05 To: Andy Goryachev , Marius Hanl Cc: openjfx-dev at openjdk.org Subject: [External] : Re: Gauging interest in bindings that can delay changing their value (debounce/throttle) Hi Andy, Those examples seem to be just timers, it would be hard to construct the primitives like throttle and debounce with these, as they don't take into account when the value last changed, or whether or not is important that the value changed again (reset timer or not). These timers would just run forever, while the functionality I propose here would have no timers running when things are stable. The timeout would also trigger precisily on the first value change. Having a running timer is more like sampling, not throttling or debouncing. The functionality I'm proposing would be more along the lines of #reduceSucessions in https://github.com/TomasMikula/ReactFX/blob/master/reactfx/src/main/java/org/reactfx/EventStream.java -- except that it would never support accumulation or combining of values (that's something for streams, not for values). --John On 03/04/2023 18:47, Andy Goryachev wrote: My two cents: I think the functionality of debouncing should better be solved by a separate facility, rather than added to observables. An example would be a use case when multiple observables trigger an expensive or delayed computation or a UI update. Something along the lines of https://github.com/TomasMikula/ReactFX/blob/master/reactfx/src/main/java/org/reactfx/util/FxTimer.java or https://github.com/andy-goryachev/FxEditor/blob/master/src/goryachev/fx/FxTimer.java cheers, -andy From: openjfx-dev on behalf of Marius Hanl Date: Thursday, March 30, 2023 at 15:20 To: John Hendrikx Cc: openjfx-dev at openjdk.org Subject: Aw: Gauging interest in bindings that can delay changing their value (debounce/throttle) + 1 for this. Debouncing is a common functionality for observables. One of the common scenarios is obviously something like a search filter functionality, where typing in characters triggers an expensive calculation. Debouncing solves the problem by doing that when nothing happened for some time, which is typically met when the user finished typing. -- Marius Gesendet: Donnerstag, 23. M?rz 2023 um 18:09 Uhr Von: "John Hendrikx" An: openjfx-dev at openjdk.org Betreff: Gauging interest in bindings that can delay changing their value (debounce/throttle) Hi list, I've been working on a potential new API (and proof of concept implementation) for adding a new type of fluent binding which can delay changing their values, and I'm wondering how much interest there is in such a thing. The main purpose of such an API is to prevent being flooded with changes when properties change often, or to simply delay certain actions until the user has settled on a selection or has stopped typing. For this purpose I would like to introduce a default method on `ObservableValue` with the signature: ObservableValue throttle(Throttler throttler); The parameter `Throttler` can be obtained via static methods of a helper class named `FXThrottlers`. These provide various pre-configured throttlers that work correctly with JavaFX's event thread model. My current proof of concept provides: public static Throttler debounce(Duration quietPeriod); public static Throttler debounceTrailing(Duration quietPeriod); public static Throttler throttle(Duration period); public static Throttler throttleTrailing(Duration period); These are variations of similar concepts, and vary mostly in when exactly they will allow value changes; debouncers will wait for a period without any changes, while throttlers will periodically allow changes. The trailing variants will not immediately emit the first change but will wait for the period to elapse first; all variants will eventually take on the value of the source observable. Debouncing is typically used when you wish for an input to settle before taking action (like typing in a search bar), while throttling is used to give regular feedback but avoid doing so too often (like feedback during window resizing). Usage example which updates a preview panel when the user has finished (cursor) scrolling through a list view: ObjectProperty selectedItem = listView.getSelectionModel().selectedItemProperty(); selectedItem .throttle(FXThrottlers.debounceTrailing(Duration.ofMillis(500))) .addListener((obs, old, current) -> { if (current != null) { updatePreviewPanel(current); } }); Implementation details: ObservableValue is part of javafx.base, and as such can't use animations or call Platform::runLater. The ThrottledBinding implementation has abstracted all of these out into the Throttler class, and FXThrottlers (which would live in javafx.graphics) therefore provides the necessary call backs to integrate property changes correctly back onto the JavaFX event thread. The Throttler class also simplifies testing; the test can provide its own timing source and background scheduler. The Throttler interface has the following methods: /** * Schedules a command to run on an unspecified thread after the time * given by {@code nanos} elapses. * * @param command a command to run, cannot be {@code null} * @param nanos a time in nanoseconds */ void schedule(Runnable command, long nanos); /** * Provides the current time in nanoseconds. * * @return the current time in nanoseconds */ long nanoTime(); /** * Runs the given command as soon as possible on a thread specified by this * throttler for updating property values. * * @param command a command to run, cannot be {@code null} */ void update(Runnable command); /** * Given the current elapsed time in the current change window, and the * amount of time elapsed since the last change was detected, determines * if and by how much the current change window should be extended. * * @param elapsed nanoseconds elapsed since the start of the current change window * @param elapsedSinceLastChange nanoseconds elapsed since the last change * @return nanoseconds to extend the window with */ long determineInterval(long elapsed, long elapsedSinceLastChange); For testing purposes, the schedule and nanoTime can be provided such that the throttle function can be tested deterministically. For integrating with JavaFX, update is implemented as `Platform.runLater(command)`. The schedule and nanoTime methods delegate to an Executor and System.nanoTime respectively. When using properties without JavaFX, Throttler implementations can be provided which run property updates on a scheduler thread (just calling Runnable::run on the current thread) or via some user provided executor. A sample test case looks like this (read with a mono space font :-)): @Test void testThrottleLeadingAndTrailing() { // create Throttler with deterministic behavior: Throttler throttler = create(Throttler.IntervalHandler.throttle(Duration.ofNanos(4)); // create throttled observable: ObservableValue binding = source.throttle(throttler); assertChanges( binding, "--a-b--c---d-----e-------f-g-----------f-g-----", "--a---b---c---d---e------f---g---------f---g---" ); assertInvalidations( binding, "--a-b--c---d-----e-------f-g-----------f-g-----", "--i---i---i---i---i------i---i---------i---i---" ); } Thanks for reading, I look forward to your feedback! --John -------------- next part -------------- An HTML attachment was scrubbed... URL: From mstrauss at openjdk.org Mon Apr 3 23:39:12 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 3 Apr 2023 23:39:12 GMT Subject: RFR: JDK-8199216: Memory leak and quadratic layout time with nested nodes (hbox) and pseudo-class in style sheet [v3] In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 07:11:07 GMT, John Hendrikx wrote: >> modules/javafx.graphics/src/main/java/com/sun/javafx/css/ImmutablePseudoClassSetsCache.java line 53: >> >>> 51: return CACHE.computeIfAbsent( >>> 52: Objects.requireNonNull(pseudoClasses, "pseudoClasses cannot be null"), >>> 53: k -> Set.copyOf(pseudoClasses) >> >> The call to `computeIfAbsent` will always do the following things: >> 1. Capture the `pseudoClasses` argument >> 2. Call `Map.get` internally >> 3. ...which calls `Set.hashCode` >> 4. ...which, for `AbstractSet.hashCode`, iterates over the entire set using an iterator and calls `hashCode` for each element. >> >> Since there is no fast path, I wonder whether this may have negative performance implications for larger scene graphs. > > I don't think there is much of an impact, scene graph size should not affect it. The sets involved are tiny, usually consisting of 1 or 2 items and very rarely 3 or possibly more(*). The hash code of `PseudoClass` is very fast, as they're singletons which don't override their hash code. > > (*) The sets are based on pseudo class combinations encountered in a Scene that would have an active role in changing the control's visual appearance. A pseudo class that doesn't affect appearance is filtered. This means usually only states like `hovered`, `focused` or `armed` have an affect. A class like `focused-within` would only be part of the set if the control involved has styles based on that class that would affect its appearance. Couldn't you just add a fast path by calculating the hash code of the immutable set eagerly and storing it in a field? This entire method could probably be written to be allocation-free if the set passed into the method is already an immutable set. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1076#discussion_r1156550443 From jpereda at openjdk.org Tue Apr 4 08:38:24 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Tue, 4 Apr 2023 08:38:24 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 22:55:16 GMT, Martin Fox wrote: >> tests/manual/events/KeyboardTest.java line 79: >> >>> 77: */ >>> 78: >>> 79: public class KeyboardTest extends Application { >> >> Could you clarify how to run the test and what one should expect? >> >> In my case, I'm running from Mac, with a Spanish physical keyboard, but changed to German keyboard from Keyboard -> Input sources -> German, and whether the Keyboard viewer is visible or not, I get: >> >> [Mac] Testing 78 keys on German without combinations >> Failed: code Numpad 0 did not produce any events >> ... >> Failed: code Decimal did not produce any events >> Tested 78 keys with 76 failures >> >> Is that expected? Is that test only meant for a German keyboard? > > @jperedadnr You set up the test correctly. I think you need to need to allow the 'terminal' application to use the accessibility API so the Java robot can send keyboard events. I can't provide you with the exact setting since I'm away from my Mac until the end of this week. When I get back I'll send details and add a comment to the test file. Apologies, I set up my Mac so long ago I forgot about this hiccup. Great, that helps: after enabling Dock -> Privacy&Security -> Accessibility -> Terminal, tests for all 5 keyboards work, but only "without combinations": [Mac] Testing 83 keys on U.S. English without combinations Tested 83 keys with 0 failures ... [Mac] Testing 78 keys on German without combinations Tested 78 keys with 0 failures However, without Keypad/All combinations fail: [Mac] Testing 80 keys on French with all combinations Failed: code A did not match combination 'A' ... Failed: code Minus did not match combination '_' Tested 80 keys with 45 failures ``` is that expected? ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1156917274 From jhendrikx at openjdk.org Tue Apr 4 09:29:22 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Tue, 4 Apr 2023 09:29:22 GMT Subject: RFR: JDK-8199216: Memory leak and quadratic layout time with nested nodes (hbox) and pseudo-class in style sheet [v3] In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 23:36:32 GMT, Michael Strau? wrote: >> I don't think there is much of an impact, scene graph size should not affect it. The sets involved are tiny, usually consisting of 1 or 2 items and very rarely 3 or possibly more(*). The hash code of `PseudoClass` is very fast, as they're singletons which don't override their hash code. >> >> (*) The sets are based on pseudo class combinations encountered in a Scene that would have an active role in changing the control's visual appearance. A pseudo class that doesn't affect appearance is filtered. This means usually only states like `hovered`, `focused` or `armed` have an affect. A class like `focused-within` would only be part of the set if the control involved has styles based on that class that would affect its appearance. > > Couldn't you just add a fast path by calculating the hash code of the immutable set eagerly and storing it in a field? This entire method could probably be written to be allocation-free if the set passed into the method is already an immutable set. I think I am missing something :) The set that is passed in may indeed be immutable, but it may not be the set we have cached. The memory savings only work when I then return the cached set; if I return the set you pass in (even if it is immutable) then we would still have large numbers of `Set` that are duplicates. So, at a minimum, the `Set` that is passed in would need its hash code calculated so I can check if it is the cached version, or otherwise return the cached version. I could cache the hash code for the sets that are returned here (they are immutable sets returned by `Set.copyOf` -- I checked their code, and they don't cache the hash codes). That would however only help if you often pass in a set that is already cached, to find out if you got the same one. Perhaps this happens a lot, I could test that. Note that `HashMap` already caches hash codes for things that are part of the map, so only the hash code of the input needs to be calculated on this call. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1076#discussion_r1156977991 From jhendrikx at openjdk.org Tue Apr 4 09:35:14 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Tue, 4 Apr 2023 09:35:14 GMT Subject: RFR: JDK-8199216: Memory leak and quadratic layout time with nested nodes (hbox) and pseudo-class in style sheet [v3] In-Reply-To: References: Message-ID: On Tue, 4 Apr 2023 09:26:21 GMT, John Hendrikx wrote: >> Couldn't you just add a fast path by calculating the hash code of the immutable set eagerly and storing it in a field? This entire method could probably be written to be allocation-free if the set passed into the method is already an immutable set. > > I think I am missing something :) > > The set that is passed in may indeed be immutable, but it may not be the set we have cached. The memory savings only work when I then return the cached set; if I return the set you pass in (even if it is immutable) then we would still have large numbers of `Set` that are duplicates. > > So, at a minimum, the `Set` that is passed in would need its hash code calculated so I can check if it is the cached version, or otherwise return the cached version. > > I could cache the hash code for the sets that are returned here (they are immutable sets returned by `Set.copyOf` -- I checked their code, and they don't cache the hash codes). That would however only help if you often pass in a set that is already cached, to find out if you got the same one. Perhaps this happens a lot, I could test that. > > Note that `HashMap` already caches hash codes for things that are part of the map, so only the hash code of the input needs to be calculated on this call. About allocation free: if the `Set` you pass in is immutable, and it is has a cached equivalent (or it is the same one), then no allocations occur (calculating the hash code does not do allocations, unless someone overrides hash code to do so) -- `copyOf` will not allocate anything if the `Set` was immutable already. Allocations only occur in two cases: - When the set you pass in is not immutable, and it is a new set that wasn't cached yet. A copy is made (allocation) and a `Map.Entry` is created (allocation) - When the set you pass in is immutable, but wasn't cached yet. No copy is needed, but still a `Map.Entry` is created. These allocations however will be only during application startup (when new combinations of pseudo classes are encountered) and the first time some state occurs in your application that results in a new pseudo class combination. The amount of allocations over the life time of your application (from this code) is probably around 50-100. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1076#discussion_r1156983700 From jhendrikx at openjdk.org Tue Apr 4 09:38:19 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Tue, 4 Apr 2023 09:38:19 GMT Subject: RFR: JDK-8199216: Memory leak and quadratic layout time with nested nodes (hbox) and pseudo-class in style sheet [v3] In-Reply-To: References: Message-ID: <71txwbPnADbrDxk1W-0jTe_8O50fqsm0MKi6F1lwVik=.d5851046-2cab-4c21-ab37-7958dfdcd6b5@github.com> On Tue, 4 Apr 2023 09:31:12 GMT, John Hendrikx wrote: >> I think I am missing something :) >> >> The set that is passed in may indeed be immutable, but it may not be the set we have cached. The memory savings only work when I then return the cached set; if I return the set you pass in (even if it is immutable) then we would still have large numbers of `Set` that are duplicates. >> >> So, at a minimum, the `Set` that is passed in would need its hash code calculated so I can check if it is the cached version, or otherwise return the cached version. >> >> I could cache the hash code for the sets that are returned here (they are immutable sets returned by `Set.copyOf` -- I checked their code, and they don't cache the hash codes). That would however only help if you often pass in a set that is already cached, to find out if you got the same one. Perhaps this happens a lot, I could test that. >> >> Note that `HashMap` already caches hash codes for things that are part of the map, so only the hash code of the input needs to be calculated on this call. > > About allocation free: if the `Set` you pass in is immutable, and it is has a cached equivalent (or it is the same one), then no allocations occur (calculating the hash code does not do allocations, unless someone overrides hash code to do so) -- `copyOf` will not allocate anything if the `Set` was immutable already. > > Allocations only occur in two cases: > - When the set you pass in is not immutable, and it is a new set that wasn't cached yet. A copy is made (allocation) and a `Map.Entry` is created (allocation) > - When the set you pass in is immutable, but wasn't cached yet. No copy is needed, but still a `Map.Entry` is created. > > These allocations however will be only during application startup (when new combinations of pseudo classes are encountered) and the first time some state occurs in your application that results in a new pseudo class combination. The amount of allocations over the life time of your application (from this code) is probably around 50-100. Perhaps write some code to show what you mean here? ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1076#discussion_r1156988973 From nlisker at openjdk.org Tue Apr 4 09:41:23 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Tue, 4 Apr 2023 09:41:23 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v5] In-Reply-To: References: Message-ID: On Sun, 2 Apr 2023 23:50:15 GMT, Michael Strau? wrote: >> `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. >> >> 1. `removeAll(c)`: >> This is a no-op if 'c' is empty. >> For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. >> >> 2. `retainAll(c)`: >> This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. >> >> I've added some tests to verify the optimized behavior for each of the three classes. > > Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: > > addressed review comments Looks good. If you choose to fix the new lines I'll re-approve. I looked at the JDK code of these methods, it seems like it could also use these optimizations. ------------- Marked as reviewed by nlisker (Reviewer). PR Review: https://git.openjdk.org/jfx/pull/751#pullrequestreview-1370588012 From dwookey at openjdk.org Tue Apr 4 10:04:23 2023 From: dwookey at openjdk.org (Dean Wookey) Date: Tue, 4 Apr 2023 10:04:23 GMT Subject: RFR: 8283551: ControlAcceleratorSupport menu items listener causes memory leak [v2] In-Reply-To: References: Message-ID: On Fri, 24 Feb 2023 10:04:48 GMT, Dean Wookey wrote: >> Each time a menu would change scenes, a new set of ListChangeListeners would be added to the items in the menu. The bigger problem however is that these list change listeners have a strong reference to the scene which is potentially a much bigger leak. >> >> The first commit was more straightforward, but there are 2 things that might be of concern: >> >> 1. The method removeAcceleratorsFromScene takes in a scene parameter, but it'll remove all the ListChangeListeners attached to it, regardless of which scene was passed in. Something similar happens with changeListenerMap already, so I think it's fine. >> 2. I made the remove method public so that external calls from skins to remove the accelerators would remove the ListChangeListener and also because all the remove methods are public. >> >> After I wrote more tests I realised using the ObservableLists as keys in the WeakHashMaps was a bad idea. If Java had a WeakIdentityHashMap the fix would be simple. The fix is in the second commit. >> >> There are still more issues that stem from the fact that for each anchor there could be multiple menus and the current code doesn't account for that. For example, swapping context menus on a tab doesn't register change listeners on the new context menu because the TabPane itself had a scene change listener already. These other issues could relate to JDK-8268374 https://bugs.openjdk.org/browse/JDK-8268374 and JDK-8283449 https://bugs.openjdk.org/browse/JDK-8283449. One of the issues is related to the fact that there's no logic to remove listeners when Tab/TableColumn's are removed from their associated control (TabPane, TableView, TreeTableView). >> >> I'm looking at these issues, but I think they're dependent on this fix. Either I can add to this PR or I can wait to see what comes out of this and fix them subsequently. > > Dean Wookey has updated the pull request incrementally with one additional commit since the last revision: > > Added more comments and fixed IdentityWrapper hashcode. Just bumping this to end it for another 4 weeks. @arapte ------------- PR Comment: https://git.openjdk.org/jfx/pull/1037#issuecomment-1495689005 From sykora at openjdk.org Tue Apr 4 10:14:14 2023 From: sykora at openjdk.org (Joeri Sykora) Date: Tue, 4 Apr 2023 10:14:14 GMT Subject: RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 [v4] In-Reply-To: References: Message-ID: <6TaBGNgmItsKyOYXPPvl28ZlzlHiMvIdqb1d5pbGzoU=.175cae64-5378-4076-9f29-f776b3f61fd5@github.com> On Mon, 3 Apr 2023 18:50:57 GMT, Hima Bindu Meda wrote: >> In Jenkins Build, the intermediate failure on windows is observed due to crash in mspdbserv.exe, which generates Program database (.pdb) files. >> Disabled the pdb file generation in order to resolve the build failure. >> Sanity testing looks fine. Verified build on windows, mac and linux. > > Hima Bindu Meda has updated the pull request incrementally with one additional commit since the last revision: > > Update proper comment All builds and tests succeeded here as well. ------------- Marked as reviewed by sykora (Author). PR Review: https://git.openjdk.org/jfx/pull/1079#pullrequestreview-1370644246 From hmeda at openjdk.org Tue Apr 4 11:47:13 2023 From: hmeda at openjdk.org (Hima Bindu Meda) Date: Tue, 4 Apr 2023 11:47:13 GMT Subject: Integrated: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 In-Reply-To: References: Message-ID: On Fri, 31 Mar 2023 07:57:11 GMT, Hima Bindu Meda wrote: > In Jenkins Build, the intermediate failure on windows is observed due to crash in mspdbserv.exe, which generates Program database (.pdb) files. > Disabled the pdb file generation in order to resolve the build failure. > Sanity testing looks fine. Verified build on windows, mac and linux. This pull request has now been integrated. Changeset: a264435d Author: Hima Bindu Meda URL: https://git.openjdk.org/jfx/commit/a264435dccba6ec386548f76f1ace095d943f4ca Stats: 9 lines in 1 file changed: 9 ins; 0 del; 0 mod 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 Reviewed-by: kcr, sykora ------------- PR: https://git.openjdk.org/jfx/pull/1079 From sykora at openjdk.org Tue Apr 4 12:02:18 2023 From: sykora at openjdk.org (Joeri Sykora) Date: Tue, 4 Apr 2023 12:02:18 GMT Subject: RFR: 8286089: Intermittent WebKit build failure on macOS in JavaScriptCore In-Reply-To: References: Message-ID: On Tue, 28 Mar 2023 02:08:27 GMT, Jay Bhaskar wrote: > Issue: Error copying file (if different) from Source/JavaScriptCore/Scripts/wkbuiltins/builtins_generate_separate_header.py" to "modules/javafx.web/build/mac/Release/JavaScriptCcripts/builtins_generate_separate_header.py". > > Root cause: The number of build threads more than 8, causing a synchronization issue for builtins_generate_separate_header.py, the file needs to be copied before use at build dir > > Solution: Use the sleep of 1 second and retry 10 times to copy in CMakeList.txt and execute using the execute_process cmake command Everything still works here as well. ------------- Marked as reviewed by sykora (Author). PR Review: https://git.openjdk.org/jfx/pull/1073#pullrequestreview-1370814874 From jbhaskar at openjdk.org Tue Apr 4 13:08:28 2023 From: jbhaskar at openjdk.org (Jay Bhaskar) Date: Tue, 4 Apr 2023 13:08:28 GMT Subject: Integrated: 8286089: Intermittent WebKit build failure on macOS in JavaScriptCore In-Reply-To: References: Message-ID: On Tue, 28 Mar 2023 02:08:27 GMT, Jay Bhaskar wrote: > Issue: Error copying file (if different) from Source/JavaScriptCore/Scripts/wkbuiltins/builtins_generate_separate_header.py" to "modules/javafx.web/build/mac/Release/JavaScriptCcripts/builtins_generate_separate_header.py". > > Root cause: The number of build threads more than 8, causing a synchronization issue for builtins_generate_separate_header.py, the file needs to be copied before use at build dir > > Solution: Use the sleep of 1 second and retry 10 times to copy in CMakeList.txt and execute using the execute_process cmake command This pull request has now been integrated. Changeset: 810bd90d Author: Jay Bhaskar URL: https://git.openjdk.org/jfx/commit/810bd90d5089364067549b8ba299300bfd208357 Stats: 26 lines in 1 file changed: 26 ins; 0 del; 0 mod 8286089: Intermittent WebKit build failure on macOS in JavaScriptCore Reviewed-by: kcr, sykora ------------- PR: https://git.openjdk.org/jfx/pull/1073 From jgneff at openjdk.org Tue Apr 4 15:46:20 2023 From: jgneff at openjdk.org (John Neffenger) Date: Tue, 4 Apr 2023 15:46:20 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v12] In-Reply-To: References: Message-ID: > This pull request allows for reproducible builds of JavaFX on Linux, macOS, and Windows by defining the `SOURCE_DATE_EPOCH` environment variable. For example, the following commands create a reproducible build: > > > $ export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) > $ bash gradlew sdk jmods javadoc > $ strip-nondeterminism -v -T $SOURCE_DATE_EPOCH build/jmods/*.jmod > > > The three commands: > > 1. set the build timestamp to the date of the latest source code change, > 2. build the JavaFX SDK libraries, JMOD archives, and API documentation, and > 3. recreate the JMOD files with stable file modification times and ordering. > > The third command won't be necessary once Gradle can build the JMOD archives or the `jmod` tool itself has the required support. For more information on the environment variable, see the [`SOURCE_DATE_EPOCH`][1] page. For more information on the command to recreate the JMOD files, see the [`strip-nondeterminism`][2] repository. I'd like to propose that we allow for reproducible builds in JavaFX 17 and consider making them the default in JavaFX 18. > > #### Fixes > > There are at least four sources of non-determinism in the JavaFX builds: > > 1. Build timestamp > > The class `com.sun.javafx.runtime.VersionInfo` in the JavaFX Base module stores the time of the build. Furthermore, for builds that don't run on the Hudson continuous integration tool, the class adds the build time to the system property `javafx.runtime.version`. > > 2. Modification times > > The JAR, JMOD, and ZIP archives store the modification time of each file. > > 3. File ordering > > The JAR, JMOD, and ZIP archives store their files in the order returned by the file system. The native shared libraries also store their object files in the order returned by the file system. Most file systems, though, do not guarantee the order of a directory's file listing. > > 4. Build path > > The class `com.sun.javafx.css.parser.Css2Bin` in the JavaFX Graphics module stores the absolute path of its `.css` input file in the corresponding `.bss` output file, which is then included in the JavaFX Controls module. > > This pull request modifies the Gradle and Groovy build files to fix the first three sources of non-determinism. A later pull request can modify the Java files to fix the fourth. > > [1]: https://reproducible-builds.org/docs/source-date-epoch/ > [2]: https://salsa.debian.org/reproducible-builds/strip-nondeterminism John Neffenger has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 21 commits: - Merge branch 'master' into allow-reproducible-builds Include two commits that fix WebKit build failures on Windows and macOS: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 8286089: Intermittent WebKit build failure on macOS in JavaScriptCore - Merge branch 'master' into allow-reproducible-builds - Support JDK 17 GA or later for building JavaFX - Merge branch 'master' into allow-reproducible-builds - Add '--date' argument for deterministic JMOD files - Merge branch 'master' into allow-reproducible-builds - Merge branch 'master' into allow-reproducible-builds - Comment out 'jmod --date' until building on JDK 19 Support for the 'jmod --date' option was added to JDK 19 starting with the 19+2 early-access build, and it was backported to JDK 17 starting with release 17.0.3. It is not available in JDK 18. - Merge 'master' into allow-reproducible-builds - Make minimal changes for new '--date' option - ... and 11 more: https://git.openjdk.org/jfx/compare/810bd90d...e42a0709 ------------- Changes: https://git.openjdk.org/jfx/pull/446/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=446&range=11 Stats: 147 lines in 7 files changed: 117 ins; 13 del; 17 mod Patch: https://git.openjdk.org/jfx/pull/446.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/446/head:pull/446 PR: https://git.openjdk.org/jfx/pull/446 From prr at openjdk.org Tue Apr 4 17:37:17 2023 From: prr at openjdk.org (Phil Race) Date: Tue, 4 Apr 2023 17:37:17 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 22:55:02 GMT, Andy Goryachev wrote: > > You mention "Thai" amongst them .. but I do see Thai rendered .. > > Thai is not rendered for me, was Ventura 13.1, now Ventura 13.3 on Mac M1, (left - ventura 13.1 with the earlier commit, right - unpatched master) So no worse off there .. and approx 20 other scripts seem to work now. Thai definitely working for me - coming from a standard Apple font called Thonburi by the looks of it. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1496350347 From angorya at openjdk.org Tue Apr 4 18:49:17 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Tue, 4 Apr 2023 18:49:17 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Fri, 24 Mar 2023 21:37:16 GMT, Phil Race wrote: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. some minor comments; overall - a great improvement. thank you, Phil! I want to share two observations that came out of testing with a RichTextArea prototype. 1. I've got java.lang.OutOfMemoryError: Java heap space UNSUPPORTED (log once): POSSIBLE ISSUE: unit 0 GLD_TEXTURE_INDEX_2D is unloadable and bound to sampler type (Float) - using zero texture because texture unloadable Screenshot 2023-04-04 at 07 55 50 I suspect it happened due to instrumentation and/or a breakpoint (I was running in Eclipse debugger and Scenic View 11.0.2 attached). I can't reproduce the issue anymore. 2. the following sequence in the RichTextAreaDemo produces an unexpected result: - type "bold plain", select "bold" and make it bold, select all set size 300%, change font to Courier New Result: the bold segment changes to regular and the regular changes to bold. It's highly probably I have a bug in my code somewhere, mentioning it here just in case. modules/javafx.graphics/src/main/java/com/sun/javafx/font/FallbackResource.java line 257: > 255: */ > 256: if (PrismFontFactory.debugFonts) { > 257: System.err.println("\tToo many font fallbacks!"); would it be better to use logging? modules/javafx.graphics/src/main/java/com/sun/javafx/font/FallbackResource.java line 376: > 374: s+= "Slot " + i + "=null\n"; > 375: } else { > 376: s += "Slot " + i + "="+getSlotResource(i).getFullName()+"\n"; minor: spaces and indentation modules/javafx.graphics/src/main/java/com/sun/javafx/font/FallbackResource.java line 379: > 377: } > 378: } > 379: s+= "\n"; perhaps it might be better to use a StringBuilder here modules/javafx.graphics/src/main/java/com/sun/javafx/font/FontFallbackInfo.java line 34: > 32: ArrayList linkedFontFiles; > 33: ArrayList linkedFontNames; > 34: ArrayList linkedFonts; could these three be `private final`? modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java line 41: > 39: class CTFontFile extends PrismFontFile { > 40: > 41: private long cgFontRef = 0; minor: the assignment is unnecessary modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java line 65: > 63: } > 64: > 65: private long ctFontRef = 0; minor: I'd add a blank line, remove the assignment. modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java line 89: > 87: if (name != null) { > 88: String family = getFamilyName(); > 89: if (family.equals("System Font")) { very minor: I'd do `System Font".equals(...)` modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java line 104: > 102: public boolean isBold() { > 103: // Need to do this until we add font variation support into the super-class > 104: return fullName.equals("System Font Bold") || super.isBold(); same here. I am sure fullName cannot be null modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTGlyphLayout.java line 83: > 81: if (fr == null) return -1; > 82: slot = fr.getSlotForFont(fontName); > 83: if (slot == -1) { minor: may be `< 0`? modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWFactory.java line 192: > 190: // CJK Ext B Supplementary character fallbacks. > 191: info.add("MingLiU-ExtB", getPathNameWindows("mingliub.ttc"), null); > 192: info.add("Segoe UI Symbol", getPathNameWindows("seguisym.ttf"), null); a question: what if these fonts are *not* available in a particular system? will the code break or it will be able to handle non-existing entry? ------------- Marked as reviewed by angorya (Committer). PR Review: https://git.openjdk.org/jfx/pull/1067#pullrequestreview-1371535673 PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1496439369 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157609552 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157611498 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157612031 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157613189 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157624589 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157625222 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157625859 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157626171 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157627666 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157630093 From angorya at openjdk.org Tue Apr 4 18:52:15 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Tue, 4 Apr 2023 18:52:15 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Fri, 24 Mar 2023 21:37:16 GMT, Phil Race wrote: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. Thai does not render for me on Ventura 13.3/M1 ![Screenshot 2023-04-04 at 11 49 03](https://user-images.githubusercontent.com/107069028/229891044-3ff3d365-6c51-48d0-8c30-759f8f376ec9.png) ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1496443468 From prr at openjdk.org Tue Apr 4 20:39:10 2023 From: prr at openjdk.org (Phil Race) Date: Tue, 4 Apr 2023 20:39:10 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Tue, 4 Apr 2023 18:49:41 GMT, Andy Goryachev wrote: > Thai does not render for me on Ventura 13.3/M1 > > ![Screenshot 2023-04-04 at 11 49 03](https://user-images.githubusercontent.com/107069028/229891044-3ff3d365-6c51-48d0-8c30-759f8f376ec9.png) On macOS 12 Thai uses Thonburi from /System/Library/Fonts/Thonburi.ttc But on macOS 13 Ventura, layout now says it uses a "dot" font version of it .ThonburiUI Regular Regular filename=/System/Library/Fonts/ThonburiUI.ttc That's OK .. except it has "Regular" twice for no reason I can see, whereas the name I see by opening the font file is just ".ThonburiUI Regular". So we think we can't find it. This looks like an Apple bug. Many fonts have "Regular" in their full name, but only this one has it twice - something in macOS is incorrectly extra appending it. Looks like the easiest thing to do is to check for this and handle as a special case. Kevin has Ventura and we just verified it solves it on his system so I'll be updating the PR shortly. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1496573282 From prr at openjdk.org Tue Apr 4 20:47:09 2023 From: prr at openjdk.org (Phil Race) Date: Tue, 4 Apr 2023 20:47:09 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v2] In-Reply-To: References: Message-ID: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. Phil Race has updated the pull request incrementally with one additional commit since the last revision: Fix up Thai font name ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1067/files - new: https://git.openjdk.org/jfx/pull/1067/files/5fb3cf5a..4e9e6f7a Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=00-01 Stats: 10 lines in 2 files changed: 9 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1067.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1067/head:pull/1067 PR: https://git.openjdk.org/jfx/pull/1067 From kcr at openjdk.org Tue Apr 4 20:48:18 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Tue, 4 Apr 2023 20:48:18 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v2] In-Reply-To: References: Message-ID: On Tue, 4 Apr 2023 20:47:09 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > Fix up Thai font name modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFactory.java line 59: > 57: System.err.println("Fix up double use of Regular in name : " + name); > 58: if (debugFonts) { > 59: } I guess you meant to put the print inside the `if (debugFonts)`? ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157745044 From prr at openjdk.org Tue Apr 4 21:15:03 2023 From: prr at openjdk.org (Phil Race) Date: Tue, 4 Apr 2023 21:15:03 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v3] In-Reply-To: References: Message-ID: <3IRMXrmApjXeweT1m2bEI6AhLSAI5SBSa8D14gVatjI=.cc93247b-9dae-45cd-be46-8e94962a33e7@github.com> > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. Phil Race has updated the pull request incrementally with one additional commit since the last revision: fix ws ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1067/files - new: https://git.openjdk.org/jfx/pull/1067/files/4e9e6f7a..18497b7c Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=01-02 Stats: 3 lines in 1 file changed: 1 ins; 1 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1067.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1067/head:pull/1067 PR: https://git.openjdk.org/jfx/pull/1067 From prr at openjdk.org Tue Apr 4 21:29:19 2023 From: prr at openjdk.org (Phil Race) Date: Tue, 4 Apr 2023 21:29:19 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v4] In-Reply-To: References: Message-ID: <3OGBCxfk1pHPN7l-XYAXKlfoNXoa-kCASW-qOLJa5IQ=.edc8523f-39ff-494d-a676-afd6654d367c@github.com> > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. Phil Race has updated the pull request incrementally with one additional commit since the last revision: formatting and make some fields private ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1067/files - new: https://git.openjdk.org/jfx/pull/1067/files/18497b7c..74a46449 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=03 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=02-03 Stats: 10 lines in 2 files changed: 0 ins; 0 del; 10 mod Patch: https://git.openjdk.org/jfx/pull/1067.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1067/head:pull/1067 PR: https://git.openjdk.org/jfx/pull/1067 From angorya at openjdk.org Tue Apr 4 21:29:22 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Tue, 4 Apr 2023 21:29:22 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v3] In-Reply-To: <3IRMXrmApjXeweT1m2bEI6AhLSAI5SBSa8D14gVatjI=.cc93247b-9dae-45cd-be46-8e94962a33e7@github.com> References: <3IRMXrmApjXeweT1m2bEI6AhLSAI5SBSa8D14gVatjI=.cc93247b-9dae-45cd-be46-8e94962a33e7@github.com> Message-ID: On Tue, 4 Apr 2023 21:15:03 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > fix ws latest changes: can see Thai on Mac, thanks! For completeness sake, the list of missing scripts on Windows 11: - Bhojpuri - Cherokee - Ge?ez - Inuktitut - Magahi - Mongolian Question: I can see Akkadian script in Eclipse, but not in javafx. So the font must be in the system, right? What would it take to find the right font? Would it be a separate issue? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1496621120 PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1496623225 PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1496625016 From prr at openjdk.org Tue Apr 4 21:29:27 2023 From: prr at openjdk.org (Phil Race) Date: Tue, 4 Apr 2023 21:29:27 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v4] In-Reply-To: References: Message-ID: On Tue, 4 Apr 2023 18:17:55 GMT, Andy Goryachev wrote: >> Phil Race has updated the pull request incrementally with one additional commit since the last revision: >> >> formatting and make some fields private > > modules/javafx.graphics/src/main/java/com/sun/javafx/font/FallbackResource.java line 257: > >> 255: */ >> 256: if (PrismFontFactory.debugFonts) { >> 257: System.err.println("\tToo many font fallbacks!"); > > would it be better to use logging? I can't change just the new cases. And changing hundreds of other cases is out of scope. > modules/javafx.graphics/src/main/java/com/sun/javafx/font/FallbackResource.java line 376: > >> 374: s+= "Slot " + i + "=null\n"; >> 375: } else { >> 376: s += "Slot " + i + "="+getSlotResource(i).getFullName()+"\n"; > > minor: spaces and indentation fixing this > modules/javafx.graphics/src/main/java/com/sun/javafx/font/FallbackResource.java line 379: > >> 377: } >> 378: } >> 379: s+= "\n"; > > perhaps it might be better to use a StringBuilder here I don't think it matters - performance isn't an issue. > modules/javafx.graphics/src/main/java/com/sun/javafx/font/FontFallbackInfo.java line 34: > >> 32: ArrayList linkedFontFiles; >> 33: ArrayList linkedFontNames; >> 34: ArrayList linkedFonts; > > could these three be `private final`? I will make them private > modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java line 41: > >> 39: class CTFontFile extends PrismFontFile { >> 40: >> 41: private long cgFontRef = 0; > > minor: the assignment is unnecessary I'd prefer to leave it. > modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java line 89: > >> 87: if (name != null) { >> 88: String family = getFamilyName(); >> 89: if (family.equals("System Font")) { > > very minor: I'd do `System Font".equals(...)` I do as you say when I'm worried about NPE. Here I'd quite like a NPE if this is null .. because there'd be something we'd need to investigate > modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java line 104: > >> 102: public boolean isBold() { >> 103: // Need to do this until we add font variation support into the super-class >> 104: return fullName.equals("System Font Bold") || super.isBold(); > > same here. I am sure fullName cannot be null right it should not be possible. > modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTGlyphLayout.java line 83: > >> 81: if (fr == null) return -1; >> 82: slot = fr.getSlotForFont(fontName); >> 83: if (slot == -1) { > > minor: may be `< 0`? We should never have -2 etc. If we do, then the code will fail and we'd know about it > modules/javafx.graphics/src/main/java/com/sun/javafx/font/directwrite/DWFactory.java line 192: > >> 190: // CJK Ext B Supplementary character fallbacks. >> 191: info.add("MingLiU-ExtB", getPathNameWindows("mingliub.ttc"), null); >> 192: info.add("Segoe UI Symbol", getPathNameWindows("seguisym.ttf"), null); > > a question: what if these fonts are *not* available in a particular system? will the code break or it will be able to handle non-existing entry? No harm. Its quite common on initial windows install to not have these fonts. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157780348 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157782480 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157783750 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157783971 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157775968 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157776846 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157777284 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157778059 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157778520 From prr at openjdk.org Tue Apr 4 21:29:28 2023 From: prr at openjdk.org (Phil Race) Date: Tue, 4 Apr 2023 21:29:28 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v2] In-Reply-To: References: Message-ID: On Tue, 4 Apr 2023 20:45:42 GMT, Kevin Rushforth wrote: >> Phil Race has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix up Thai font name > > modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFactory.java line 59: > >> 57: System.err.println("Fix up double use of Regular in name : " + name); >> 58: if (debugFonts) { >> 59: } > > I guess you meant to put the print inside the `if (debugFonts)`? fixed ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1157778743 From angorya at openjdk.org Tue Apr 4 21:35:17 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Tue, 4 Apr 2023 21:35:17 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v4] In-Reply-To: <3OGBCxfk1pHPN7l-XYAXKlfoNXoa-kCASW-qOLJa5IQ=.edc8523f-39ff-494d-a676-afd6654d367c@github.com> References: <3OGBCxfk1pHPN7l-XYAXKlfoNXoa-kCASW-qOLJa5IQ=.edc8523f-39ff-494d-a676-afd6654d367c@github.com> Message-ID: On Tue, 4 Apr 2023 21:29:19 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > formatting and make some fields private Question: I see multiple stderr output: Fix up double use of Regular in name : .ThonburiUI Regular Regular Fix up double use of Regular in name : .ThonburiUI Regular Regular Fix up double use of Regular in name : .ThonburiUI Regular Regular Fix up double use of Regular in name : .ThonburiUI Regular Regular Is this normal? Should it happen only once? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1496632079 From kcr at openjdk.org Tue Apr 4 23:30:28 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Tue, 4 Apr 2023 23:30:28 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v12] In-Reply-To: References: Message-ID: On Tue, 4 Apr 2023 15:46:20 GMT, John Neffenger wrote: >> This pull request allows for reproducible builds of JavaFX on Linux, macOS, and Windows by defining the `SOURCE_DATE_EPOCH` environment variable. For example, the following commands create a reproducible build: >> >> >> $ export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) >> $ bash gradlew sdk jmods javadoc >> $ strip-nondeterminism -v -T $SOURCE_DATE_EPOCH build/jmods/*.jmod >> >> >> The three commands: >> >> 1. set the build timestamp to the date of the latest source code change, >> 2. build the JavaFX SDK libraries, JMOD archives, and API documentation, and >> 3. recreate the JMOD files with stable file modification times and ordering. >> >> The third command won't be necessary once Gradle can build the JMOD archives or the `jmod` tool itself has the required support. For more information on the environment variable, see the [`SOURCE_DATE_EPOCH`][1] page. For more information on the command to recreate the JMOD files, see the [`strip-nondeterminism`][2] repository. I'd like to propose that we allow for reproducible builds in JavaFX 17 and consider making them the default in JavaFX 18. >> >> #### Fixes >> >> There are at least four sources of non-determinism in the JavaFX builds: >> >> 1. Build timestamp >> >> The class `com.sun.javafx.runtime.VersionInfo` in the JavaFX Base module stores the time of the build. Furthermore, for builds that don't run on the Hudson continuous integration tool, the class adds the build time to the system property `javafx.runtime.version`. >> >> 2. Modification times >> >> The JAR, JMOD, and ZIP archives store the modification time of each file. >> >> 3. File ordering >> >> The JAR, JMOD, and ZIP archives store their files in the order returned by the file system. The native shared libraries also store their object files in the order returned by the file system. Most file systems, though, do not guarantee the order of a directory's file listing. >> >> 4. Build path >> >> The class `com.sun.javafx.css.parser.Css2Bin` in the JavaFX Graphics module stores the absolute path of its `.css` input file in the corresponding `.bss` output file, which is then included in the JavaFX Controls module. >> >> This pull request modifies the Gradle and Groovy build files to fix the first three sources of non-determinism. A later pull request can modify the Java files to fix the fourth. >> >> [1]: https://reproducible-builds.org/docs/source-date-epoch/ >> [2]: https://salsa.debian.org/reproducible-builds/strip-nondeterminism > > John Neffenger has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 21 commits: > > - Merge branch 'master' into allow-reproducible-builds > > Include two commits that fix WebKit build failures on Windows and macOS: > > 8282359: Intermittent WebKit build failure on Windows: > C1090: PDB API call failed, error code 23 > 8286089: Intermittent WebKit build failure on macOS in JavaScriptCore > - Merge branch 'master' into allow-reproducible-builds > - Support JDK 17 GA or later for building JavaFX > - Merge branch 'master' into allow-reproducible-builds > - Add '--date' argument for deterministic JMOD files > - Merge branch 'master' into allow-reproducible-builds > - Merge branch 'master' into allow-reproducible-builds > - Comment out 'jmod --date' until building on JDK 19 > > Support for the 'jmod --date' option was added to JDK 19 starting > with the 19+2 early-access build, and it was backported to JDK 17 > starting with release 17.0.3. It is not available in JDK 18. > - Merge 'master' into allow-reproducible-builds > - Make minimal changes for new '--date' option > - ... and 11 more: https://git.openjdk.org/jfx/compare/810bd90d...e42a0709 I started doing some testing today. I verified that without `SOURCE_DATE_EPOCH` set, the builds are as expected with a couple minor diffs. 1. The jar index in `javafx-swt.jar` is gone. This is fine (as mentioned earlier), since jar indexing is not useful for modular jars. There is an in-progress RFE remove some support for it in the JDK with [JDK-8302819](https://bugs.openjdk.org/browse/JDK-8302819), so I was going to file an issue for us to stop using it, but now I don't have to. 2. The format of `VersionInfo.BUILD_TIMESTAMP`, which is used in constructing the `javafx.runtime.version` System property for dev builds, has changed to an ISO date -- `2023-04-04T15:11:59Z` rather than `2023-04-04-151159`. Since the `:` is not legal for Java version strings, it is possible (though unlikely), that some app is parsing this in a way that might run into porblems. This should probably be fixed. I then did a build with `SOURCE_DATE_EPOCH`. On each of three machines I tried (one each of Windows, Linux, and Mac / x64), a pair of builds with the same `SOURCE_DATE_EPOCH` were identical except for the native WebKit library, which was different between the two builds on Windows and Linux (Mac was fine). All other artifacts (except, by extension, `javafx.web.jmod`) were identical. Unless there is an easy solution, I think addressing the jfxwebkit native library differences on Windows and Linux could be handled via a follow-on issue. I'll do a review of the changes later this week along with some more testing. ------------- PR Comment: https://git.openjdk.org/jfx/pull/446#issuecomment-1496720090 From duke at openjdk.org Tue Apr 4 23:41:24 2023 From: duke at openjdk.org (Martin Fox) Date: Tue, 4 Apr 2023 23:41:24 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: References: Message-ID: On Tue, 4 Apr 2023 08:35:52 GMT, Jose Pereda wrote: >> @jperedadnr You set up the test correctly. I think you need to need to allow the 'terminal' application to use the accessibility API so the Java robot can send keyboard events. I can't provide you with the exact setting since I'm away from my Mac until the end of this week. When I get back I'll send details and add a comment to the test file. Apologies, I set up my Mac so long ago I forgot about this hiccup. > > Great, that helps: after enabling Dock -> Privacy&Security -> Accessibility -> Terminal, tests for all 5 keyboards work, but only "without combinations": > > [Mac] Testing 83 keys on U.S. English without combinations > Tested 83 keys with 0 failures > ... > [Mac] Testing 78 keys on German without combinations > Tested 78 keys with 0 failures > > However, without Keypad/All combinations fail: > > [Mac] Testing 80 keys on French with all combinations > Failed: code A did not match combination 'A' > ... > Failed: code Minus did not match combination '_' > Tested 80 keys with 45 failures > ``` > is that expected? Yes, the KeyCharacterCombination failures are expected. Fixing those will require a separate PR. I?m hoping Linux PR #694 will be accepted and then I can extend that approach to the Mac. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1157864676 From jgneff at openjdk.org Wed Apr 5 00:32:22 2023 From: jgneff at openjdk.org (John Neffenger) Date: Wed, 5 Apr 2023 00:32:22 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v12] In-Reply-To: References: Message-ID: <_QCTuJmnz5OdcKvLX1EIGGUbLchEXq9paN0pYl6jTk0=.ba424497-70c0-46a3-9594-12f08aa13c0d@github.com> On Tue, 4 Apr 2023 23:27:38 GMT, Kevin Rushforth wrote: > I started doing some testing today. Thank you, Kevin. I'm almost done with another round of my own testing and will post my results, too. > 2. The format of `VersionInfo.BUILD_TIMESTAMP`, which is used in constructing the `javafx.runtime.version` System property for dev builds, has changed to an ISO date -- `2023-04-04T15:11:59Z` rather than `2023-04-04-151159`. Since the `:` is not legal for Java version strings, it is possible (though unlikely), that some app is parsing this in a way that might run into problems. This should probably be fixed. It always bothered me that developer builds get a timestamp suffix while the official builds do not, even when built from the same Git tag. For example: $ cat opt/javafx-sdk-20/lib/javafx.properties javafx.version=20 javafx.runtime.version=20+19 javafx.runtime.build=19 $ cat /snap/openjfx/current/sdk/lib/javafx.properties javafx.version=20 javafx.runtime.version=20+19-2023-03-07-164252 javafx.runtime.build=19 That makes it impossible for a developer to reproduce an identical copy of the official build. Would it be more appropriate to use the output of `git describe`? For example, below is the command's output for this pull request branch and for the `20+11` tag: $ git describe 21+11-25-ge42a070947 $ git describe allow-reproducible-builds 21+11-25-ge42a070947 $ git describe 20+11 20+11 The JDK does something similar for its `release` file: $ cat opt/jdk-20/release IMPLEMENTOR="Oracle Corporation" JAVA_VERSION="20" JAVA_VERSION_DATE="2023-03-21" LIBC="gnu" ... OS_ARCH="x86_64" OS_NAME="Linux" SOURCE=".:git:82749901b149" ------------- PR Comment: https://git.openjdk.org/jfx/pull/446#issuecomment-1496766710 From mstrauss at openjdk.org Wed Apr 5 05:24:20 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Wed, 5 Apr 2023 05:24:20 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v4] In-Reply-To: References: Message-ID: <0fh5aaJQuPu89KtapA4rci1wKdBMIYL8i5w8US4xOIg=.e14e96ea-d840-4b34-b1f6-cf4f15be63c2@github.com> On Sat, 1 Apr 2023 22:14:09 GMT, John Hendrikx wrote: >> Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: >> >> addressed review comments, added tests > > Looks really good now! @hjohn Can you re-approve? ------------- PR Comment: https://git.openjdk.org/jfx/pull/751#issuecomment-1496932930 From jhendrikx at openjdk.org Wed Apr 5 10:14:22 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Wed, 5 Apr 2023 10:14:22 GMT Subject: RFR: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll [v5] In-Reply-To: References: Message-ID: On Sun, 2 Apr 2023 23:50:15 GMT, Michael Strau? wrote: >> `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. >> >> 1. `removeAll(c)`: >> This is a no-op if 'c' is empty. >> For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. >> >> 2. `retainAll(c)`: >> This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. >> >> I've added some tests to verify the optimized behavior for each of the three classes. > > Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: > > addressed review comments Marked as reviewed by jhendrikx (Committer). ------------- PR Review: https://git.openjdk.org/jfx/pull/751#pullrequestreview-1372587188 From mstrauss at openjdk.org Wed Apr 5 12:11:27 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Wed, 5 Apr 2023 12:11:27 GMT Subject: Integrated: 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll In-Reply-To: References: Message-ID: On Sat, 12 Mar 2022 04:57:37 GMT, Michael Strau? wrote: > `Observable{List/Set/Map}Wrapper.retainAll/removeAll` can be optimized for some edge cases. > > 1. `removeAll(c)`: > This is a no-op if 'c' is empty. > For `ObservableListWrapper`, returning early skips an object allocation. For `ObservableSetWrapper` and `ObservableMapWrapper`, returning early prevents an enumeration of the entire collection. > > 2. `retainAll(c)`: > This is a no-op if the backing collection is empty, or equivalent to `clear()` if `c` is empty. > > I've added some tests to verify the optimized behavior for each of the three classes. This pull request has now been integrated. Changeset: b6e5737c Author: Michael Strau? URL: https://git.openjdk.org/jfx/commit/b6e5737c7a25544f61778254613a4dd42ca2b96c Stats: 988 lines in 11 files changed: 964 ins; 8 del; 16 mod 8283063: Optimize Observable{List/Set/Map}Wrapper.retainAll/removeAll Reviewed-by: nlisker, jhendrikx ------------- PR: https://git.openjdk.org/jfx/pull/751 From tsayao at openjdk.org Wed Apr 5 12:22:18 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Wed, 5 Apr 2023 12:22:18 GMT Subject: RFR: 8223373: Remove IntelliJ IDEA specific files from the source code repository In-Reply-To: <1Zuhx1POpw-Litlg8LjiyoghThmnsznMc-1n2m31wqQ=.6af58850-bd6e-4409-9acb-ef2a928c5e8e@github.com> References: <1Zuhx1POpw-Litlg8LjiyoghThmnsznMc-1n2m31wqQ=.6af58850-bd6e-4409-9acb-ef2a928c5e8e@github.com> Message-ID: <1P24Sp9x3kFwePoomKrehJaBpMRV5jcweYTtfFRooZY=.defd10ea-62f5-4129-93cd-9be843072fb7@github.com> On Tue, 31 Jan 2023 18:20:05 GMT, Kevin Rushforth wrote: >> This PR does: >> >> - Remove specific Idea files and let it be imported from gradle; >> - Adds checkstyle (to use with checkstyle plugin - it will let you know style mistakes); >> - Configures auto-format to sun style (with the changes mentioned in [Code Style Rules](https://wiki.openjdk.org/display/OpenJFX/Code+Style+Rules)); >> - Automatically sets Copyright notice (updates year too); >> - Run configurations for samples/toys and builds. > > This touches `build.gradle` and `settings.gradle` in addition to IDE-specific files. Those changes will need additional review, so I'm requesting two reviewers. @kevinrushforth I've reverted the gradle changes, so it pretty much only affect the IDE. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1009#issuecomment-1497394217 From jpereda at openjdk.org Wed Apr 5 13:33:29 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Wed, 5 Apr 2023 13:33:29 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: References: Message-ID: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> On Tue, 21 Mar 2023 22:49:34 GMT, Martin Fox wrote: >> This PR adds code to ensure that KeyCodeCombinations match KeyEvents as expected by more accurately mapping from a Mac key code to a Java key code based on the user?s active keyboard layout (the existing code assumes a US QWERTY layout). The new code first identifies a set of Mac keys which can produce different characters based on the user?s keyboard layout. A Mac key code outside that area is processed exactly as before. For a key inside the layout-sensitive area the code calls UCKeyTranslate to translate the key to an unshifted ASCII character based on the active keyboard and uses that to determine the Java key code. >> >> When performing the reverse mapping for the Robot the code first uses the old QWERTY mapping to find a candidate key. If it lies in the layout-sensitive area the code then scans the entire area calling UCKeyTranslate until it finds a match. If the key lies outside the layout-sensitive area it?s processed exactly as before. >> >> There are multiple duplicates of these bugs logged against Mac applications built with JavaFX. >> >> https://bugs.openjdk.java.net/browse/JDK-8090257 Mac: Inconsistent KeyEvents with alternative keyboard layouts >> https://bugs.openjdk.java.net/browse/JDK-8088120 [Accelerator, Mac] CMD + Z accelerator is not working with French keyboard >> https://bugs.openjdk.java.net/browse/JDK-8087915 Mac: accelerator doesn't take into account azerty keyboard layout >> https://bugs.openjdk.java.net/browse/JDK-8150709 Mac OSX and German Keyboard Layout (Y/Z) > > Martin Fox has updated the pull request incrementally with one additional commit since the last revision: > > Added manual cross-platform keyboard handling test I tested on Mac Ventura the manual test. Fails without the patch for all languages, passes with it for all of them. I've left some comments, but the PR looks good. buildSrc/mac.gradle line 156: > 154: "-framework", "AppKit", > 155: "-framework", "ApplicationServices", > 156: "-framework", "Carbon", Change license header copyright to 2023 modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 34: > 32: #import "GlassKey.h" > 33: > 34: #import Change license header copyright to 2023 modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 195: > 193: } > 194: > 195: if (keyCode >= 0x00 && keyCode <= 0x32) Add a comment? like `// Null to [Space]` modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 195: > 193: } > 194: > 195: if (keyCode >= 0x00 && keyCode <= 0x32) out of curiosity, why not? ` if ((keyCode >= 0x00 && keyCode <= 0x32) || (keyCode >= 0x5D && keyCode <= 0x5F))` modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 198: > 196: return YES; > 197: > 198: if (keyCode >= 0x5D && keyCode <= 0x5F) same: `'' to ']'` modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 330: > 328: // A handful of keyboards (Azeri, Turkmen, and Sami variants) can only access > 329: // critical letters like Q by using the Option key in conjunction with Cmd. > 330: // In this API the Cmd flag suppresses the Option flag so we ommit Cmd. typo s/ommit/omit modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 473: > 471: // If the QWERTY key is in the layout sensitive area search the other keys in that > 472: // area. We may not find a key so returning NO is possible. > 473: for (unsigned short trialKey = 0x00; trialKey <= 0x7E; ++trialKey) I see this as a last resource, in case everything else failed so far. But I wonder if this could be slow? Also given that keyCode in sensitive layout is true only for [0x00 - 0x32] and 0x5D, 0x5F, maybe you could improve this? tests/manual/events/KeyboardTest.java line 78: > 76: * KeyCharacterCombinations don't work reliably on most platforms (for now). > 77: */ > 78: As discussed before, please add a comment on how to enable Terminal access to Accessibility features. tests/manual/events/KeyboardTest.java line 458: > 456: GERMAN("German", KeyListBuilder.germanKeys()), > 457: LATIN("Latin", KeyListBuilder.latinKeys()), > 458: NON_LATIN("non-Latin", KeyListBuilder.nonLatinKeys()); How hard would be adding another languages to this test, like Spanish? I see that you already commented that the robot can't access dead keys (so no possible test for `?` for instance...)? tests/manual/events/KeyboardTest.java line 458: > 456: GERMAN("German", KeyListBuilder.germanKeys()), > 457: LATIN("Latin", KeyListBuilder.latinKeys()), > 458: NON_LATIN("non-Latin", KeyListBuilder.nonLatinKeys()); Out of curiosity, I tested Cantonese keyboard with Non-Latin, got this printout: 2023-04-05 15:25:55.539 java[8997:135623] +[CATransaction synchronize] called within transaction not sure what it means or if it is relevant? ------------- PR Review: https://git.openjdk.org/jfx/pull/425#pullrequestreview-1372819730 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158482688 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158482779 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158460512 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158463612 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158462598 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158468865 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158477269 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158480033 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158517055 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158519520 From duke at openjdk.org Wed Apr 5 14:03:26 2023 From: duke at openjdk.org (przemSzer) Date: Wed, 5 Apr 2023 14:03:26 GMT Subject: RFR: 8297130: ComboBox popup doesn't close after selecting value that was added with 'runLater' In-Reply-To: References: Message-ID: On Sat, 19 Nov 2022 18:01:41 GMT, Michael Strau? wrote: > This PR fixes a bug where multi-level focus is not correctly preserved. > The original implementation incorrectly assumed that there can only be a single focused node in the scene graph, which is not the case when a branch of the scene graph is presented by a `PopupWindow`. More specifically, when a focused node was removed from the scene graph, the focus flags of all parents were incorrectly cleared. The correct implementation only clears the `focusWithin` flag of parents (but not `focused` or `focusVisible`), and stops when another focused node is encountered along the way. Do you plan to add this fix to the version 19, of Java FX? ------------- PR Comment: https://git.openjdk.org/jfx/pull/956#issuecomment-1497514138 From kcr at openjdk.org Wed Apr 5 14:02:24 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Wed, 5 Apr 2023 14:02:24 GMT Subject: RFR: 8304441: [macos] Crash when putting invalid unicode char on clipboard In-Reply-To: <6AADnJNah6umVMFeVYodgaBdDoVnDj5UicoE6IST0Kk=.a63ed42d-16ad-4901-aa8b-3f5fac9f64ea@github.com> References: <6AADnJNah6umVMFeVYodgaBdDoVnDj5UicoE6IST0Kk=.a63ed42d-16ad-4901-aa8b-3f5fac9f64ea@github.com> Message-ID: On Tue, 28 Mar 2023 15:09:29 GMT, Kevin Rushforth wrote: > A malformed unicode string containing only half of a surrogate pair (either a high or low surrogate without the other half) will cause a native exception in the macOS `NSPasteboardItem setString:forType:` method. This uncaught exception will terminate (crash) the application. > > The fix is to validate the string before calling `setString:forType:`. I also added a try / catch that logs a warning, so that if we ever run into other exceptions, they won't be fatal. > > I added an automated test that fails on macOS without the fix and passes with the fix. The test is run on other platforms as well, and passes both before and after the fix. @andy-goryachev-oracle : can you be the second reviewer on this? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1074#issuecomment-1497536324 From kcr at openjdk.org Wed Apr 5 14:18:36 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Wed, 5 Apr 2023 14:18:36 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v12] In-Reply-To: <_QCTuJmnz5OdcKvLX1EIGGUbLchEXq9paN0pYl6jTk0=.ba424497-70c0-46a3-9594-12f08aa13c0d@github.com> References: <_QCTuJmnz5OdcKvLX1EIGGUbLchEXq9paN0pYl6jTk0=.ba424497-70c0-46a3-9594-12f08aa13c0d@github.com> Message-ID: On Wed, 5 Apr 2023 00:29:40 GMT, John Neffenger wrote: > > 2. The format of `VersionInfo.BUILD_TIMESTAMP`, which is used in constructing the `javafx.runtime.version` System property for dev builds, has changed to an ISO date -- `2023-04-04T15:11:59Z` rather than `2023-04-04-151159`. Since the `:` is not legal for Java version strings, it is possible (though unlikely), that some app is parsing this in a way that might run into problems. This should probably be fixed. > > It always bothered me that developer builds get a timestamp suffix while the official builds do not, even when built from the same Git tag. For example: > ... We could consider a future RFE to adjust the format of the version string, although I note that the JDK also adds the date code to the version string only for developer builds. > > ``` > $ cat opt/javafx-sdk-20/lib/javafx.properties > javafx.version=20 > javafx.runtime.version=20+19 > javafx.runtime.build=19 > $ cat /snap/openjfx/current/sdk/lib/javafx.properties > javafx.version=20 > javafx.runtime.version=20+19-2023-03-07-164252 > javafx.runtime.build=19 > ``` > > That makes it impossible for a developer to reproduce an identical copy of the official build. No it doesn't. What it does mean is that they would need to set the following properties to the same values that were used for the official build: HUDSON_JOB_NAME HUDSON_BUILD_NUMBER PROMOTED_BUILD_NUMBER MILESTONE_FCS and, of course: CONF=Release > Would it be more appropriate to use the output of `git describe`? For example, below is the command's output for this pull request branch and for the `21+11` tag: > > ``` > $ git describe > 21+11-25-ge42a070947 > $ git describe allow-reproducible-builds > 21+11-25-ge42a070947 > $ git describe 21+11 > 21+11 Not for the version string, but we could consider a future RFE to add something along these lines to the `lib/javafx.properties` file (which is the closest thing we have to the JDK's `release` file). ------------- PR Comment: https://git.openjdk.org/jfx/pull/446#issuecomment-1497566465 From kevin.rushforth at oracle.com Wed Apr 5 15:16:02 2023 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Wed, 5 Apr 2023 08:16:02 -0700 Subject: OpenJFX, async image decoding on MacOS In-Reply-To: <010201875187d2cd-30bd21fb-ec77-4fb6-9155-e85af7ebf2c2-000000@eu-west-1.amazonses.com> References: <001c01d967bf$9dbf6180$d93e2480$@musicincite.buzz> <010201875187d2cd-30bd21fb-ec77-4fb6-9155-e85af7ebf2c2-000000@eu-west-1.amazonses.com> Message-ID: <35172382-e9c3-c55f-32f7-599939f215c9@oracle.com> As mentioned in a reply to another message, the right place to discuss JavaFX issues is openjfx-dev at openjdk.org . Do you have a self-contained ".html" file that demonstrates the problem? -- Kevin On 4/5/2023 6:07 AM, Jerry Kramskoy wrote: > > Hi Guys, > > Any does not get rendered on JDK/JFX19 (MacOS). > > Works fine on Windows 10. > > This shows up with WordPress 6.1 up, whose default is to using async > decoding to speed up Web page loading. > > This can be disabled via a WordPress API call, but this then penalises > SEO scoring. > > Are you aware of this?? I?m guessing the ECMAScript engine that ships > with MacOS version of WebView/WebEngine doesn?t support async. > > Thanks, Jerry Kramskoy > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kcr at openjdk.org Wed Apr 5 16:33:23 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Wed, 5 Apr 2023 16:33:23 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> References: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> Message-ID: On Wed, 5 Apr 2023 13:26:59 GMT, Jose Pereda wrote: >> Martin Fox has updated the pull request incrementally with one additional commit since the last revision: >> >> Added manual cross-platform keyboard handling test > > tests/manual/events/KeyboardTest.java line 458: > >> 456: GERMAN("German", KeyListBuilder.germanKeys()), >> 457: LATIN("Latin", KeyListBuilder.latinKeys()), >> 458: NON_LATIN("non-Latin", KeyListBuilder.nonLatinKeys()); > > Out of curiosity, I tested Cantonese keyboard with Non-Latin, got this printout: > > 2023-04-05 15:25:55.539 java[8997:135623] +[CATransaction synchronize] called within transaction > > not sure what it means or if it is relevant? If this goes through IME, it's a known problem on macOS 13 (Ventura) : https://bugs.openjdk.org/browse/JDK-8301878 ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1158755912 From prr at openjdk.org Wed Apr 5 16:49:12 2023 From: prr at openjdk.org (Phil Race) Date: Wed, 5 Apr 2023 16:49:12 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v5] In-Reply-To: References: Message-ID: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. Phil Race has updated the pull request incrementally with one additional commit since the last revision: Send some additional scripts to layout ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1067/files - new: https://git.openjdk.org/jfx/pull/1067/files/74a46449..eb02a264 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=04 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=03-04 Stats: 34 lines in 1 file changed: 33 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1067.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1067/head:pull/1067 PR: https://git.openjdk.org/jfx/pull/1067 From prr at openjdk.org Wed Apr 5 16:49:12 2023 From: prr at openjdk.org (Phil Race) Date: Wed, 5 Apr 2023 16:49:12 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v4] In-Reply-To: <3OGBCxfk1pHPN7l-XYAXKlfoNXoa-kCASW-qOLJa5IQ=.edc8523f-39ff-494d-a676-afd6654d367c@github.com> References: <3OGBCxfk1pHPN7l-XYAXKlfoNXoa-kCASW-qOLJa5IQ=.edc8523f-39ff-494d-a676-afd6654d367c@github.com> Message-ID: On Tue, 4 Apr 2023 21:29:19 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > formatting and make some fields private I have pushed an update that should help some additional scripts be rendered on macOS if there is font support ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1497807967 From prr at openjdk.org Wed Apr 5 17:50:17 2023 From: prr at openjdk.org (Phil Race) Date: Wed, 5 Apr 2023 17:50:17 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v6] In-Reply-To: References: Message-ID: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. Phil Race has updated the pull request incrementally with one additional commit since the last revision: Look for unicode platform names ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1067/files - new: https://git.openjdk.org/jfx/pull/1067/files/eb02a264..e4ce97a5 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=05 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=04-05 Stats: 9 lines in 1 file changed: 6 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jfx/pull/1067.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1067/head:pull/1067 PR: https://git.openjdk.org/jfx/pull/1067 From jerry.kramskoy at musicincite.buzz Wed Apr 5 18:04:58 2023 From: jerry.kramskoy at musicincite.buzz (=?UTF-8?Q?Jerry_Kramskoy?=) Date: Wed, 5 Apr 2023 18:04:58 +0000 Subject: bug on JDK/JFX19 (MacOS) WebView/WebEngine References: <000f01d967e9$21293590$637ba0b0$@musicincite.buzz> Message-ID: <010201875297e41a-8d03b736-d4ec-4770-ae41-9c2e8274158e-000000@eu-west-1.amazonses.com> Hi Guys, ? Any does not get rendered on JDK/JFX19 (MacOS) WebView/WebEngine ? Works fine on Windows 10. ? This shows up with WordPress 6.1 up, whose default is to using async decoding to speed up Web page loading. This can be disabled via a WordPress API call, but this then penalises SEO scoring. ? Are you aware of this?? ?I?m guessing the ECMAScript engine that ships with MacOS version of WebView/WebEngine doesn?t support async. ? It doesn?t show up in browsers on MacOS (11 ?) ? I?ve attached a standalone html file that demonstrates the problem.? If the ?decoding=?async? is edited out, all works. ? Thanks, Jerry Kramskoy ? -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- An HTML attachment was scrubbed... URL: From jerry.kramskoy at musicincite.buzz Wed Apr 5 18:09:32 2023 From: jerry.kramskoy at musicincite.buzz (=?UTF-8?Q?Jerry_Kramskoy?=) Date: Wed, 5 Apr 2023 18:09:32 +0000 Subject: WebP support References: <001e01d967e9$c4a79c20$4df6d460$@musicincite.buzz> Message-ID: <01020187529c129a-7ed04aa6-bfed-4280-964d-8a0a0286893c-000000@eu-west-1.amazonses.com> Hi Guys, Are there plans to support WebP soon?? Lack of support means that SEO is getting penalised for sites that JavaFX can load, as the page load speed is often poor by comparison. In my case, I have a music education site that becomes interactive when loaded via my JavaFX application (e.g. to create a guitar scale on a virtual guitar (Canvas)), but can be browsed normally with none of these interactions. ? WebP is becoming very important these days, especially with SEO in mind. ? Many thanks, Jerry Kramskoy -------------- next part -------------- An HTML attachment was scrubbed... URL: From prr at openjdk.org Wed Apr 5 18:59:06 2023 From: prr at openjdk.org (Phil Race) Date: Wed, 5 Apr 2023 18:59:06 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v7] In-Reply-To: References: Message-ID: <-KnABnUwf4YdZneCIAFc0b0bo0W876zme6mypgthP6Q=.a74db335-df31-4f45-8d74-d791254546e9@github.com> > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. Phil Race has updated the pull request incrementally with one additional commit since the last revision: move check for double regular ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1067/files - new: https://git.openjdk.org/jfx/pull/1067/files/e4ce97a5..ed1a6e9d Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=06 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=05-06 Stats: 18 lines in 2 files changed: 9 ins; 9 del; 0 mod Patch: https://git.openjdk.org/jfx/pull/1067.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1067/head:pull/1067 PR: https://git.openjdk.org/jfx/pull/1067 From zjx001202 at gmail.com Wed Apr 5 19:06:05 2023 From: zjx001202 at gmail.com (Glavo) Date: Thu, 6 Apr 2023 03:06:05 +0800 Subject: WebP support In-Reply-To: <01020187529c129a-7ed04aa6-bfed-4280-964d-8a0a0286893c-000000@eu-west-1.amazonses.com> References: <001e01d967e9$c4a79c20$4df6d460$@musicincite.buzz> <01020187529c129a-7ed04aa6-bfed-4280-964d-8a0a0286893c-000000@eu-west-1.amazonses.com> Message-ID: As a reference, TwelveMonkeys[1] implemented WebP support for ImageIO in Java. I have recently done some work on WebP support for JavaFX, but I have no experience in image processing, and I am also busy with many other tasks. If there are experts in this field willing to start implementing it in the near future, I would be happy that it has saved me a lot of time. Glavo [1] https://github.com/haraldk/TwelveMonkeys On Thu, Apr 6, 2023 at 2:50?AM Jerry Kramskoy wrote: > Hi Guys, > > Are there plans to support WebP soon? Lack of support means that SEO is > getting penalised for sites that JavaFX can load, as the page load speed is > often poor by comparison. > > In my case, I have a music education site that becomes interactive when > loaded via my JavaFX application (e.g. to create a guitar scale on a > virtual guitar (Canvas)), but can be browsed normally with none of these > interactions. > > > > WebP is becoming very important these days, especially with SEO in mind. > > > > Many thanks, Jerry Kramskoy > -------------- next part -------------- An HTML attachment was scrubbed... URL: From prr at openjdk.org Wed Apr 5 19:07:25 2023 From: prr at openjdk.org (Phil Race) Date: Wed, 5 Apr 2023 19:07:25 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v8] In-Reply-To: References: Message-ID: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. Phil Race has updated the pull request incrementally with one additional commit since the last revision: fix ranges ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1067/files - new: https://git.openjdk.org/jfx/pull/1067/files/ed1a6e9d..4bee80ce Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=07 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=06-07 Stats: 4 lines in 1 file changed: 0 ins; 0 del; 4 mod Patch: https://git.openjdk.org/jfx/pull/1067.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1067/head:pull/1067 PR: https://git.openjdk.org/jfx/pull/1067 From angorya at openjdk.org Wed Apr 5 19:26:18 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Wed, 5 Apr 2023 19:26:18 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v8] In-Reply-To: References: Message-ID: On Wed, 5 Apr 2023 19:07:25 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > fix ranges I see all the scripts that gave us problem rendered with this PR. Thank you so much, Phil! To express my feelings, in Akkadian: ![Screenshot 2023-04-05 at 12 18 29](https://user-images.githubusercontent.com/107069028/230183723-29f82785-1339-42ba-9d4f-41f39d24301d.png) ------------- Marked as reviewed by angorya (Committer). PR Review: https://git.openjdk.org/jfx/pull/1067#pullrequestreview-1373544981 From kevin.rushforth at oracle.com Wed Apr 5 19:32:44 2023 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Wed, 5 Apr 2023 12:32:44 -0700 Subject: bug on JDK/JFX19 (MacOS) WebView/WebEngine In-Reply-To: <010201875297e41a-8d03b736-d4ec-4770-ae41-9c2e8274158e-000000@eu-west-1.amazonses.com> References: <000f01d967e9$21293590$637ba0b0$@musicincite.buzz> <010201875297e41a-8d03b736-d4ec-4770-ae41-9c2e8274158e-000000@eu-west-1.amazonses.com> Message-ID: I can reproduce it. It renders fine on Windows and Linux, and fails to render on Mac. I also confirmed that removing the async works. I filed https://bugs.openjdk.org/browse/JDK-8305674 to track this. It reproduces with a simplified html file (a single image). Thanks for reporting it. -- Kevin On 4/5/2023 11:04 AM, Jerry Kramskoy wrote: > > Hi Guys, > > Any does not get rendered on JDK/JFX19 > (MacOS) WebView/WebEngine > > Works fine on Windows 10. > > This shows up with WordPress 6.1 up, whose default is to using async > decoding to speed up Web page loading. > > This can be disabled via a WordPress API call, but this then penalises > SEO scoring. > > Are you aware of this?? ?I?m guessing the ECMAScript engine that ships > with MacOS version of WebView/WebEngine doesn?t support async. > > It doesn?t show up in browsers on MacOS (11 ?) > > I?ve attached a standalone html file that demonstrates the problem.? > If the ?decoding=?async? is edited out, all works. > > Thanks, Jerry Kramskoy > -------------- next part -------------- An HTML attachment was scrubbed... URL: From angorya at openjdk.org Wed Apr 5 22:29:15 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Wed, 5 Apr 2023 22:29:15 GMT Subject: RFR: 8304441: [macos] Crash when putting invalid unicode char on clipboard In-Reply-To: <6AADnJNah6umVMFeVYodgaBdDoVnDj5UicoE6IST0Kk=.a63ed42d-16ad-4901-aa8b-3f5fac9f64ea@github.com> References: <6AADnJNah6umVMFeVYodgaBdDoVnDj5UicoE6IST0Kk=.a63ed42d-16ad-4901-aa8b-3f5fac9f64ea@github.com> Message-ID: <1Isz6LQCnNRzgB2kEYDxdYNGAsEWBrhlm0DQpnR2J_Y=.fc412cea-e3aa-414b-b599-deaea4cd4615@github.com> On Tue, 28 Mar 2023 15:09:29 GMT, Kevin Rushforth wrote: > A malformed unicode string containing only half of a surrogate pair (either a high or low surrogate without the other half) will cause a native exception in the macOS `NSPasteboardItem setString:forType:` method. This uncaught exception will terminate (crash) the application. > > The fix is to validate the string before calling `setString:forType:`. I also added a try / catch that logs a warning, so that if we ever run into other exceptions, they won't be fatal. > > I added an automated test that fails on macOS without the fix and passes with the fix. The test is run on other platforms as well, and passes both before and after the fix. Does not crash, does not output to stderr when copying with a missing surrogate. The character itself is being copied as is, which is expected behavior. ------------- Marked as reviewed by angorya (Committer). PR Review: https://git.openjdk.org/jfx/pull/1074#pullrequestreview-1373780425 From jgneff at openjdk.org Thu Apr 6 05:22:21 2023 From: jgneff at openjdk.org (John Neffenger) Date: Thu, 6 Apr 2023 05:22:21 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v12] In-Reply-To: References: Message-ID: <9a9SvEVo6lQdiLDVyItmgLdphyDSiiOqeJsyxYa5VuU=.df65254f-bdd8-4962-84e9-ea7cac78c2c4@github.com> On Tue, 4 Apr 2023 15:46:20 GMT, John Neffenger wrote: >> This pull request allows for reproducible builds of JavaFX on Linux, macOS, and Windows by defining the `SOURCE_DATE_EPOCH` environment variable. For example, the following commands create a reproducible build: >> >> >> $ export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) >> $ bash gradlew sdk jmods javadoc >> $ strip-nondeterminism -v -T $SOURCE_DATE_EPOCH build/jmods/*.jmod >> >> >> The three commands: >> >> 1. set the build timestamp to the date of the latest source code change, >> 2. build the JavaFX SDK libraries, JMOD archives, and API documentation, and >> 3. recreate the JMOD files with stable file modification times and ordering. >> >> The third command won't be necessary once Gradle can build the JMOD archives or the `jmod` tool itself has the required support. For more information on the environment variable, see the [`SOURCE_DATE_EPOCH`][1] page. For more information on the command to recreate the JMOD files, see the [`strip-nondeterminism`][2] repository. I'd like to propose that we allow for reproducible builds in JavaFX 17 and consider making them the default in JavaFX 18. >> >> #### Fixes >> >> There are at least four sources of non-determinism in the JavaFX builds: >> >> 1. Build timestamp >> >> The class `com.sun.javafx.runtime.VersionInfo` in the JavaFX Base module stores the time of the build. Furthermore, for builds that don't run on the Hudson continuous integration tool, the class adds the build time to the system property `javafx.runtime.version`. >> >> 2. Modification times >> >> The JAR, JMOD, and ZIP archives store the modification time of each file. >> >> 3. File ordering >> >> The JAR, JMOD, and ZIP archives store their files in the order returned by the file system. The native shared libraries also store their object files in the order returned by the file system. Most file systems, though, do not guarantee the order of a directory's file listing. >> >> 4. Build path >> >> The class `com.sun.javafx.css.parser.Css2Bin` in the JavaFX Graphics module stores the absolute path of its `.css` input file in the corresponding `.bss` output file, which is then included in the JavaFX Controls module. >> >> This pull request modifies the Gradle and Groovy build files to fix the first three sources of non-determinism. A later pull request can modify the Java files to fix the fourth. >> >> [1]: https://reproducible-builds.org/docs/source-date-epoch/ >> [2]: https://salsa.debian.org/reproducible-builds/strip-nondeterminism > > John Neffenger has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 21 commits: > > - Merge branch 'master' into allow-reproducible-builds > > Include two commits that fix WebKit build failures on Windows and macOS: > > 8282359: Intermittent WebKit build failure on Windows: > C1090: PDB API call failed, error code 23 > 8286089: Intermittent WebKit build failure on macOS in JavaScriptCore > - Merge branch 'master' into allow-reproducible-builds > - Support JDK 17 GA or later for building JavaFX > - Merge branch 'master' into allow-reproducible-builds > - Add '--date' argument for deterministic JMOD files > - Merge branch 'master' into allow-reproducible-builds > - Merge branch 'master' into allow-reproducible-builds > - Comment out 'jmod --date' until building on JDK 19 > > Support for the 'jmod --date' option was added to JDK 19 starting > with the 19+2 early-access build, and it was backported to JDK 17 > starting with release 17.0.3. It is not available in JDK 18. > - Merge 'master' into allow-reproducible-builds > - Make minimal changes for new '--date' option > - ... and 11 more: https://git.openjdk.org/jfx/compare/810bd90d...e42a0709 Thanks for finding this, Kevin. For my own reference, the format of the Java version string is explained in the API specification of [Runtime.Version][1], which defines the `$OPT` additional build information as matching the regular expression `([-a-zA-Z0-9.]+)`. No colon characters are permitted. > We could consider a future RFE to adjust the format of the version string, although I note that the JDK also adds the date code to the version string only for developer builds. The JDK [removed the timestamp][2] in version 9 for [JDK-8170632][3], so now they look something like `20-internal+36-adhoc.root.build`. More to your point, I now see that the JDK also adds additional information by default, just like JavaFX. > No it doesn't. What it does mean is that they would need to set the following properties to the same values that were used for the official build: Right. Sorry, I should have known that after all the "release" builds I do for this pull request! I would like to replace the current non-standard build timestamp with one that conforms to ISO 8601. This pull request uses the ISO 8601 *extended* format, but the standard also defines a *basic* format that does result in a valid Java version `OPT` field. [The consensus][4] seems to be that both the date and time must use the same format type, either extended or basic, which makes the current JavaFX build timestamp non-standard. [1]: https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/lang/Runtime.Version.html [2]: https://github.com/openjdk/jdk/commit/e262ab65 [3]: https://bugs.openjdk.org/browse/JDK-8170632 [4]: https://stackoverflow.com/q/44870006 What do you think about simply replacing this pull request's extended format with the basic format? See the following sample program for details: import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.Date; public class Timestamp { private static final String OPT = "([-a-zA-Z0-9.]+)"; private static final String OK = " (okay)"; private static final String NOT_OK = " (NOT okay)"; public static void main(String[] args) { // ISO 8601 extended format var buildInstant = Instant.now().truncatedTo(ChronoUnit.SECONDS); String extended = buildInstant.toString(); // Non-standard format used in the current JavaFX release var buildDate = Date.from(buildInstant); var format = new SimpleDateFormat("yyyy-MM-dd-HHmmss"); String current = format.format(buildDate); // ISO 8601 basic format var localTime = LocalDateTime.ofInstant(buildInstant, ZoneOffset.UTC); var formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'"); String basic = localTime.format(formatter); System.out.print("ISO 8601 extended format = " + extended); System.out.println(extended.matches(OPT) ? OK : NOT_OK); System.out.print("Current JavaFX format = " + current); System.out.println(current.matches(OPT) ? OK : NOT_OK); System.out.print("ISO 8601 basic format = " + basic); System.out.println(basic.matches(OPT) ? OK : NOT_OK); } } An example of its output is shown below: $ java Timestamp ISO 8601 extended format = 2023-04-06T04:20:16Z (NOT okay) Current JavaFX format = 2023-04-05-212016 (okay) ISO 8601 basic format = 20230406T042016Z (okay) ------------- PR Comment: https://git.openjdk.org/jfx/pull/446#issuecomment-1498506001 From duke at openjdk.org Thu Apr 6 06:41:19 2023 From: duke at openjdk.org (Fabian Wolter) Date: Thu, 6 Apr 2023 06:41:19 GMT Subject: RFR: 8087370: [odroid] Monocle: Touch is still broken on Odroid In-Reply-To: <8r1cERIcJeZVLWYcG3EqWV7zKEoDqtLLgqBVHlPIUyI=.9f7e72c8-de1a-49f6-9df2-8d6a5f46174a@github.com> References: <8r1cERIcJeZVLWYcG3EqWV7zKEoDqtLLgqBVHlPIUyI=.9f7e72c8-de1a-49f6-9df2-8d6a5f46174a@github.com> Message-ID: On Wed, 13 Oct 2021 10:52:40 GMT, Fabian Wolter wrote: > There are sometimes multitouch events detected, when only a single touch should be detected under certain conditions. This lead to touch events on previous touch positions. > > The referenced bug is closed with "won't fix" with the justification it would be platform specific. But this is not correct. It affects all Linux platforms combined with a touch controller, which sends the touch events in an uncommon, but valid(!), order. > > We encountered this problem with the touch controller ILI2511 with firmware V6000_V1 in the Tianma display TM070JVHG33. This patch fixes the problem. It is the same patch attached to above bug report. Do you need any additional information to start reviewing this bug? ------------- PR Comment: https://git.openjdk.org/jfx/pull/641#issuecomment-1498565486 From kevin.rushforth at oracle.com Thu Apr 6 11:31:52 2023 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Thu, 6 Apr 2023 04:31:52 -0700 Subject: WebP support In-Reply-To: References: <001e01d967e9$c4a79c20$4df6d460$@musicincite.buzz> <01020187529c129a-7ed04aa6-bfed-4280-964d-8a0a0286893c-000000@eu-west-1.amazonses.com> Message-ID: <9de47d65-eafe-ac51-8af8-53a8d485cac5@oracle.com> There are no current plans to implement a new image loader for the WebP format. As with any new feature, if enough application developers would benefit from it, and if there is someone willing to drive the feature, then we could consider it. One caveat, though, is that it would need to be done without using any third-party code, since you can't contribute any code you don't own under the terms of the OCA, and we (Oracle) are unlikely to want to take on another third-party library for this functionality. -- Kevin On 4/5/2023 12:06 PM, Glavo wrote: > As a reference, TwelveMonkeys[1] implemented WebP support for ImageIO > in Java. > > I have recently done some work on WebP support for JavaFX, but I have > no experience in image processing, > and I am also busy with many other tasks.?If there are experts in this > field willing to start implementing it in the near future, > I would be happy that it has saved me a lot of time. > > Glavo > > [1] https://github.com/haraldk/TwelveMonkeys > > On Thu, Apr 6, 2023 at 2:50?AM Jerry Kramskoy > wrote: > > Hi Guys, > > Are there plans to support WebP soon?? Lack of support means that > SEO is getting penalised for sites that JavaFX can load, as the > page load speed is often poor by comparison. > > In my case, I have a music education site that becomes interactive > when loaded via my JavaFX application (e.g. to create a guitar > scale on a virtual guitar (Canvas)), but can be browsed normally > with none of these interactions. > > WebP is becoming very important these days, especially with SEO in > mind. > > Many thanks, Jerry Kramskoy > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kcr at openjdk.org Thu Apr 6 11:38:16 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Thu, 6 Apr 2023 11:38:16 GMT Subject: Integrated: 8304441: [macos] Crash when putting invalid unicode char on clipboard In-Reply-To: <6AADnJNah6umVMFeVYodgaBdDoVnDj5UicoE6IST0Kk=.a63ed42d-16ad-4901-aa8b-3f5fac9f64ea@github.com> References: <6AADnJNah6umVMFeVYodgaBdDoVnDj5UicoE6IST0Kk=.a63ed42d-16ad-4901-aa8b-3f5fac9f64ea@github.com> Message-ID: On Tue, 28 Mar 2023 15:09:29 GMT, Kevin Rushforth wrote: > A malformed unicode string containing only half of a surrogate pair (either a high or low surrogate without the other half) will cause a native exception in the macOS `NSPasteboardItem setString:forType:` method. This uncaught exception will terminate (crash) the application. > > The fix is to validate the string before calling `setString:forType:`. I also added a try / catch that logs a warning, so that if we ever run into other exceptions, they won't be fatal. > > I added an automated test that fails on macOS without the fix and passes with the fix. The test is run on other platforms as well, and passes both before and after the fix. This pull request has now been integrated. Changeset: 2b2a7f1f Author: Kevin Rushforth URL: https://git.openjdk.org/jfx/commit/2b2a7f1f7cdad676159d471d2fee6025bbf4e939 Stats: 115 lines in 2 files changed: 113 ins; 0 del; 2 mod 8304441: [macos] Crash when putting invalid unicode char on clipboard Reviewed-by: prr, angorya ------------- PR: https://git.openjdk.org/jfx/pull/1074 From jhendrikx at openjdk.org Thu Apr 6 11:47:14 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Thu, 6 Apr 2023 11:47:14 GMT Subject: RFR: 8302816: Refactor sorting-related classes In-Reply-To: References: Message-ID: <8NAjOrQW_E5lS4sEM4UaEcvS5069tIYZqDDlftajBYQ=.920c2b31-cd5a-440a-9756-4bb55238a937@github.com> On Sat, 18 Feb 2023 17:59:12 GMT, Nir Lisker wrote: > Most of the changes revolve around unifying the sorting methods for a collection with `Comparable` elements with sorting methods that take an external `Comparator` by passing `Comparator.naturalOrder()` from the former to the latter. This eliminates method duplication and some warnings suppressions. > > Note that I get 1 failing test: VersionInfoTest.testMajorVersion. This PR is unrelated to this test. Looks good, no comments. There are some documentation changes in public API, is a csr needed? ------------- Marked as reviewed by jhendrikx (Committer). PR Review: https://git.openjdk.org/jfx/pull/1041#pullrequestreview-1374695119 PR Comment: https://git.openjdk.org/jfx/pull/1041#issuecomment-1498933647 From jpereda at openjdk.org Thu Apr 6 11:51:22 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Thu, 6 Apr 2023 11:51:22 GMT Subject: RFR: 8278938: [Win] Robot can target wrong key for punctuation and symbols [v2] In-Reply-To: References: Message-ID: On Wed, 12 Jan 2022 20:45:02 GMT, Martin Fox wrote: >> When processing a `WM_CHAR` event on an OEM key (punctuation, symbol, dead key) the glass code will dynamically query the key's unshifted character to determine the Java code to assign to it. This is necessary since the relationship between OEM key codes and the characters they generate varies from layout to layout. >> >> The Robot implementation was consulting a table which assumed a fixed relationship between Java codes and Windows key codes even for the OEM keys. The table was also missing entries for any Java code not on a US QWERTY layout, like PLUS. >> >> In this PR if we don't find the Java code in the table or if it maps to an OEM key (which may be wrong) we sweep through all the OEM keys looking for the matching Java code. > > Martin Fox has updated the pull request incrementally with one additional commit since the last revision: > > A Robot now correctly handles KeyCodes that aren't in the current layout PR looks good and works fine on Windows 11. I've tested the test attached to the JBS issue with a Spanish keyboard. It fails without the patch for `+`, `'`, `?`, and passes with it. There is a NPE if you press AltGr (with or without the patch): Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: keyCode must not be null at java.base/java.util.Objects.requireNonNull(Objects.java:233) at javafx.graphics at 21-internal/javafx.scene.robot.Robot.keyPress(Robot.java:92) at RobotKeySanityTest.lambda$userReleasedEvent$0(RobotKeySanityTest.java:121) ``` I wonder if RobotKeySanityTest could be part of the PR as a manual test? Same as in #694 modules/javafx.graphics/src/main/native-glass/win/KeyTable.cpp line 188: > 186: } > 187: > 188: static UINT const oemKeys[] = { update license header copyright modules/javafx.graphics/src/main/native-glass/win/KeyTable.h line 32: > 30: void JavaKeyToWindowsKey(jint jkey, UINT &vkey, UINT &modifiers); > 31: BOOL IsExtendedKey(UINT vkey); > 32: jint OEMCharToJavaKey(UINT ch, bool deadKey); update license header copyright modules/javafx.graphics/src/main/native-glass/win/ViewContainer.cpp line 409: > 407: if (unicodeConverted < 0) { > 408: // Dead key > 409: switch (wChar[0]) { update license header copyright ------------- PR Review: https://git.openjdk.org/jfx/pull/702#pullrequestreview-1374678712 PR Review Comment: https://git.openjdk.org/jfx/pull/702#discussion_r1159677954 PR Review Comment: https://git.openjdk.org/jfx/pull/702#discussion_r1159678087 PR Review Comment: https://git.openjdk.org/jfx/pull/702#discussion_r1159678139 From kcr at openjdk.org Thu Apr 6 12:03:19 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Thu, 6 Apr 2023 12:03:19 GMT Subject: RFR: 8302816: Refactor sorting-related classes In-Reply-To: <8NAjOrQW_E5lS4sEM4UaEcvS5069tIYZqDDlftajBYQ=.920c2b31-cd5a-440a-9756-4bb55238a937@github.com> References: <8NAjOrQW_E5lS4sEM4UaEcvS5069tIYZqDDlftajBYQ=.920c2b31-cd5a-440a-9756-4bb55238a937@github.com> Message-ID: On Thu, 6 Apr 2023 11:43:57 GMT, John Hendrikx wrote: > There are some documentation changes in public API, is a csr needed? Thanks for checking. Since the changes are simple clarification, I'm OK letting this in without a CSR. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1041#issuecomment-1498951696 From jhendrikx at openjdk.org Thu Apr 6 12:10:19 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Thu, 6 Apr 2023 12:10:19 GMT Subject: RFR: 8299348: Size-restricted window can be observed with incorrect dimensions In-Reply-To: <9zNyOtonYujDxiJZQQs_Xtx8ewS63NLff04eebFzEWU=.8ddb924d-d8cd-49bb-a61e-ec2c447c9ad0@github.com> References: <9zNyOtonYujDxiJZQQs_Xtx8ewS63NLff04eebFzEWU=.8ddb924d-d8cd-49bb-a61e-ec2c447c9ad0@github.com> Message-ID: On Mon, 26 Dec 2022 03:03:50 GMT, Michael Strau? wrote: > On Windows, a `Stage` that is restricted by minimum and maximum sizes can briefly be observed to appear with incorrect dimensions when it is first shown. The root cause of this bug is that the native `WinWindow._setBounds` method doesn't respect min/max sizes when calculating the window rect. > > Note to reviewers: I've removed the unused `GlassWindow::updateMinMaxSize` method as to not confuse readers where min-max handling actually happens. This looks like a good change to me. Code also looks good. ------------- Marked as reviewed by jhendrikx (Committer). PR Review: https://git.openjdk.org/jfx/pull/984#pullrequestreview-1374726668 From kpk at openjdk.org Thu Apr 6 13:08:12 2023 From: kpk at openjdk.org (Karthik P K) Date: Thu, 6 Apr 2023 13:08:12 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu Message-ID: When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. Added system test to validate the fix. ------------- Commit messages: - Add copyright text to fxml - Fix NPE in submenu of context menu Changes: https://git.openjdk.org/jfx/pull/1082/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1082&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8088594 Stats: 342 lines in 6 files changed: 324 ins; 17 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1082.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1082/head:pull/1082 PR: https://git.openjdk.org/jfx/pull/1082 From kcr at openjdk.org Thu Apr 6 16:30:23 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Thu, 6 Apr 2023 16:30:23 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v8] In-Reply-To: References: Message-ID: <1vfXbvjr7tdJzaHIG0WRoL6SFspzTLSjPlsllRYWXVE=.9e2bcba3-32f8-480d-81fe-e5c861c63243@github.com> On Wed, 5 Apr 2023 19:07:25 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > fix ranges I see some new test failures on macOS 13 Ventura (not sure if they reproduce on macOS 12 or earlier). System Tests: `HTMLEditorTest` Web Tests: `MiscellaneousTest --> testFontFace` ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1499326487 From kcr at openjdk.org Thu Apr 6 16:52:23 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Thu, 6 Apr 2023 16:52:23 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v8] In-Reply-To: References: Message-ID: On Wed, 5 Apr 2023 19:07:25 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > fix ranges modules/javafx.graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java line 245: > 243: * Probably this should be handled elsewhere > 244: */ > 245: if (isMacOSX && name.startsWith("System ")) { `name` can be null, so you need a null check here. This is the cause of the unit test failures. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1160039669 From mstrauss at openjdk.org Thu Apr 6 17:24:20 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Thu, 6 Apr 2023 17:24:20 GMT Subject: RFR: JDK-8245919: Region#padding property rendering error In-Reply-To: References: Message-ID: On Mon, 27 Mar 2023 23:05:00 GMT, John Hendrikx wrote: > Fix bug in CSS caching code that could reset values on unrelated nodes. > > The bug occurs due to a cache entry being constructed incorrectly when the initial node that triggered the cache entry creation has user set values. The calculated values for properties with a user set value were omitted in the cache entry, and other nodes that later share the same entry would incorrectly assume the omitted property was unstyled and were therefore reset to their default values. Looks good to me. modules/javafx.graphics/src/test/java/test/javafx/scene/CssStyleHelperTest.java line 614: > 612: > 613: @Test > 614: public void initialNodeWithUserSetValueShouldNotResetValuesOnOtherNodesWithoutOverridenValue() throws IOException { Typo: "Overridden" ------------- Marked as reviewed by mstrauss (Committer). PR Review: https://git.openjdk.org/jfx/pull/1072#pullrequestreview-1375287875 PR Review Comment: https://git.openjdk.org/jfx/pull/1072#discussion_r1160067506 From mstrauss at openjdk.org Thu Apr 6 17:38:15 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Thu, 6 Apr 2023 17:38:15 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed In-Reply-To: References: Message-ID: On Fri, 10 Mar 2023 05:19:13 GMT, John Hendrikx wrote: > Description copied from issue: > > There are up to two additional invalidations performed that really should be avoided, causing downstream fluent bindings to be recomputed with the same values. This is very confusing as these should only be called when there is an actual change, and not called for the same value multiple times in a row. > > These two extra invalidations have two different causes, each causing an additional invalidation to be triggered: > > 1) ObjectBinding's `isObserved` is delayed slightly. When you add a listener, the listener is added internally and the binding is made valid; this triggers some downstream activity which checks the `isObserved` status to decide whether to start observation of properties -- unfortunately this still returns `false` at that time. A work-around for this existed by calling `getValue` again in `LazyObjectBinding` with a huge comment explaining why this is needed. Although this works, it still means that a downstream function like `map` is called an additional time while it should really only be called once. > > The solution is to ensure `isObserved` returns `true` before the `ExpressionHelper` is called. Already verified this solves the problem. This also means the work-around in `LazyObjectBinding` is no longer needed, which seems like a big win. > > 2) The second additional call originates from a different issue. When `ConditionalBinding` (which implements the `when` construct) sees its condition property changing, it always invalidates itself. This is however only necessary if the current cached value (if it was valid) differs from the current source value. To prevent an unnecessary invalidation, and the resulting revalidation calls that this will trigger, a simple check to see if the value actually changed before invalidating solves this problem. Looks good to me. modules/javafx.base/src/main/java/javafx/beans/binding/ObjectBinding.java line 66: > 64: private T value; > 65: private boolean valid = false; > 66: private boolean isObserved; Minor: "observed" might be more consistent with the field naming convention in this file. modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 1: > 1: package test.javafx.beans.value; This file is missing a copyright header. ------------- Marked as reviewed by mstrauss (Committer). PR Review: https://git.openjdk.org/jfx/pull/1056#pullrequestreview-1375304698 PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1160080910 PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1160079643 From prr at openjdk.org Thu Apr 6 17:45:14 2023 From: prr at openjdk.org (Phil Race) Date: Thu, 6 Apr 2023 17:45:14 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v9] In-Reply-To: References: Message-ID: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. Phil Race has updated the pull request incrementally with one additional commit since the last revision: Fix NPE ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1067/files - new: https://git.openjdk.org/jfx/pull/1067/files/4bee80ce..0a1104ef Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=08 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=07-08 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1067.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1067/head:pull/1067 PR: https://git.openjdk.org/jfx/pull/1067 From prr at openjdk.org Thu Apr 6 17:45:17 2023 From: prr at openjdk.org (Phil Race) Date: Thu, 6 Apr 2023 17:45:17 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v8] In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 16:49:34 GMT, Kevin Rushforth wrote: >> Phil Race has updated the pull request incrementally with one additional commit since the last revision: >> >> fix ranges > > modules/javafx.graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java line 245: > >> 243: * Probably this should be handled elsewhere >> 244: */ >> 245: if (isMacOSX && name.startsWith("System ")) { > > `name` can be null, so you need a null check here. This is the cause of the unit test failures. fixed ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1160085423 From kcr at openjdk.org Thu Apr 6 19:54:19 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Thu, 6 Apr 2023 19:54:19 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v9] In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 17:45:14 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > Fix NPE Looks good to me, with one place where a NULL check would be a good idea. All my testing is green. modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java line 276: > 274: System.err.println("Cascading list for " + getFullName()); > 275: } > 276: for (int i=0; i 253: return NULL; > 254: } > 255: jlong *refArr = calloc(cnt, sizeof(jlong)); I recommend checking the return value for null. ------------- PR Review: https://git.openjdk.org/jfx/pull/1067#pullrequestreview-1375414069 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1160151124 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1160187111 From prr at openjdk.org Thu Apr 6 20:06:04 2023 From: prr at openjdk.org (Phil Race) Date: Thu, 6 Apr 2023 20:06:04 GMT Subject: RFR: 8304041: [WebView] Text on the left and right of emoji is not visible Message-ID: This fixes a problem with mixing Emoji and regular text in Webview. The Prism implementation expects that Emoji will not be in the same call to drawString as regular glyphs, since they need very different handling. This fix breaks up the runs webview hands to Prism. The test program in the bug report now renders properly (which it never did before in any release) ------------- Commit messages: - 8304041 Changes: https://git.openjdk.org/jfx/pull/1083/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1083&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8304041 Stats: 55 lines in 1 file changed: 54 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1083.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1083/head:pull/1083 PR: https://git.openjdk.org/jfx/pull/1083 From prr at openjdk.org Thu Apr 6 20:17:15 2023 From: prr at openjdk.org (Phil Race) Date: Thu, 6 Apr 2023 20:17:15 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v10] In-Reply-To: References: Message-ID: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. Phil Race has updated the pull request incrementally with one additional commit since the last revision: Fix formatting and NPE ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1067/files - new: https://git.openjdk.org/jfx/pull/1067/files/0a1104ef..c11bf1cb Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=09 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1067&range=08-09 Stats: 6 lines in 2 files changed: 5 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1067.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1067/head:pull/1067 PR: https://git.openjdk.org/jfx/pull/1067 From prr at openjdk.org Thu Apr 6 20:17:20 2023 From: prr at openjdk.org (Phil Race) Date: Thu, 6 Apr 2023 20:17:20 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v9] In-Reply-To: References: Message-ID: <6yodx85jasPgWgGxvLwJ1NT-wlPfXE_47qimcdIpmBc=.131a765e-1773-4ff2-88e0-a311a0d7354b@github.com> On Thu, 6 Apr 2023 18:57:34 GMT, Kevin Rushforth wrote: >> Phil Race has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix NPE > > modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTFontFile.java line 276: > >> 274: System.err.println("Cascading list for " + getFullName()); >> 275: } >> 276: for (int i=0; i > Minor: add space after `;` done > modules/javafx.graphics/src/main/native-font/MacFontFinder.c line 255: > >> 253: return NULL; >> 254: } >> 255: jlong *refArr = calloc(cnt, sizeof(jlong)); > > I recommend checking the return value for null. done ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1160207465 PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1160207372 From kizune at openjdk.org Thu Apr 6 20:48:16 2023 From: kizune at openjdk.org (Alexander Zuev) Date: Thu, 6 Apr 2023 20:48:16 GMT Subject: RFR: 8301312: Create implementation of NSAccessibilityButton protocol Message-ID: Add the common base component for all the new implementing native classes Change native peer creation to use the new base component The new code will instantiate new protocol implementation for the given role if it exists or an old one if it does not exist Added BUTTON role implementing class ------------- Commit messages: - 8301312: Create implementation of NSAccessibilityButton protocol Changes: https://git.openjdk.org/jfx/pull/1084/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1084&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8301312 Stats: 361 lines in 7 files changed: 325 ins; 29 del; 7 mod Patch: https://git.openjdk.org/jfx/pull/1084.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1084/head:pull/1084 PR: https://git.openjdk.org/jfx/pull/1084 From kcr at openjdk.org Thu Apr 6 21:00:24 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Thu, 6 Apr 2023 21:00:24 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v10] In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 20:17:15 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > Fix formatting and NPE Marked as reviewed by kcr (Lead). @johanvos did you have any comments on this PR? ------------- PR Review: https://git.openjdk.org/jfx/pull/1067#pullrequestreview-1375565990 PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1499620982 From angorya at openjdk.org Thu Apr 6 21:00:25 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Thu, 6 Apr 2023 21:00:25 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v10] In-Reply-To: References: Message-ID: <49IZSCBfqpM5XYwkRZclGkuJNNWpE-hI4SrH5o9HXBY=.4ecaa35a-0ead-443c-bbf0-74c3ed33b506@github.com> On Thu, 6 Apr 2023 20:17:15 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > Fix formatting and NPE Marked as reviewed by angorya (Committer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1067#pullrequestreview-1375566646 From jgneff at openjdk.org Fri Apr 7 06:22:05 2023 From: jgneff at openjdk.org (John Neffenger) Date: Fri, 7 Apr 2023 06:22:05 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v13] In-Reply-To: References: Message-ID: <_WXDVDoiGezrJmltUlcPkKflohZhoWjwjYQedH93PIE=.65682e52-8f40-47f3-8cfd-ce0251ebac97@github.com> > This pull request allows for reproducible builds of JavaFX on Linux, macOS, and Windows by defining the `SOURCE_DATE_EPOCH` environment variable. For example, the following commands create a reproducible build: > > > $ export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) > $ bash gradlew sdk jmods javadoc > $ strip-nondeterminism -v -T $SOURCE_DATE_EPOCH build/jmods/*.jmod > > > The three commands: > > 1. set the build timestamp to the date of the latest source code change, > 2. build the JavaFX SDK libraries, JMOD archives, and API documentation, and > 3. recreate the JMOD files with stable file modification times and ordering. > > The third command won't be necessary once Gradle can build the JMOD archives or the `jmod` tool itself has the required support. For more information on the environment variable, see the [`SOURCE_DATE_EPOCH`][1] page. For more information on the command to recreate the JMOD files, see the [`strip-nondeterminism`][2] repository. I'd like to propose that we allow for reproducible builds in JavaFX 17 and consider making them the default in JavaFX 18. > > #### Fixes > > There are at least four sources of non-determinism in the JavaFX builds: > > 1. Build timestamp > > The class `com.sun.javafx.runtime.VersionInfo` in the JavaFX Base module stores the time of the build. Furthermore, for builds that don't run on the Hudson continuous integration tool, the class adds the build time to the system property `javafx.runtime.version`. > > 2. Modification times > > The JAR, JMOD, and ZIP archives store the modification time of each file. > > 3. File ordering > > The JAR, JMOD, and ZIP archives store their files in the order returned by the file system. The native shared libraries also store their object files in the order returned by the file system. Most file systems, though, do not guarantee the order of a directory's file listing. > > 4. Build path > > The class `com.sun.javafx.css.parser.Css2Bin` in the JavaFX Graphics module stores the absolute path of its `.css` input file in the corresponding `.bss` output file, which is then included in the JavaFX Controls module. > > This pull request modifies the Gradle and Groovy build files to fix the first three sources of non-determinism. A later pull request can modify the Java files to fix the fourth. > > [1]: https://reproducible-builds.org/docs/source-date-epoch/ > [2]: https://salsa.debian.org/reproducible-builds/strip-nondeterminism John Neffenger has updated the pull request incrementally with one additional commit since the last revision: Revert format of timestamp in version OPT field ------------- Changes: - all: https://git.openjdk.org/jfx/pull/446/files - new: https://git.openjdk.org/jfx/pull/446/files/e42a0709..46b1670a Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=446&range=12 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=446&range=11-12 Stats: 8 lines in 1 file changed: 6 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jfx/pull/446.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/446/head:pull/446 PR: https://git.openjdk.org/jfx/pull/446 From jgneff at openjdk.org Fri Apr 7 06:27:07 2023 From: jgneff at openjdk.org (John Neffenger) Date: Fri, 7 Apr 2023 06:27:07 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v13] In-Reply-To: <_WXDVDoiGezrJmltUlcPkKflohZhoWjwjYQedH93PIE=.65682e52-8f40-47f3-8cfd-ce0251ebac97@github.com> References: <_WXDVDoiGezrJmltUlcPkKflohZhoWjwjYQedH93PIE=.65682e52-8f40-47f3-8cfd-ce0251ebac97@github.com> Message-ID: On Fri, 7 Apr 2023 06:22:05 GMT, John Neffenger wrote: >> This pull request allows for reproducible builds of JavaFX on Linux, macOS, and Windows by defining the `SOURCE_DATE_EPOCH` environment variable. For example, the following commands create a reproducible build: >> >> >> $ export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) >> $ bash gradlew sdk jmods javadoc >> $ strip-nondeterminism -v -T $SOURCE_DATE_EPOCH build/jmods/*.jmod >> >> >> The three commands: >> >> 1. set the build timestamp to the date of the latest source code change, >> 2. build the JavaFX SDK libraries, JMOD archives, and API documentation, and >> 3. recreate the JMOD files with stable file modification times and ordering. >> >> The third command won't be necessary once Gradle can build the JMOD archives or the `jmod` tool itself has the required support. For more information on the environment variable, see the [`SOURCE_DATE_EPOCH`][1] page. For more information on the command to recreate the JMOD files, see the [`strip-nondeterminism`][2] repository. I'd like to propose that we allow for reproducible builds in JavaFX 17 and consider making them the default in JavaFX 18. >> >> #### Fixes >> >> There are at least four sources of non-determinism in the JavaFX builds: >> >> 1. Build timestamp >> >> The class `com.sun.javafx.runtime.VersionInfo` in the JavaFX Base module stores the time of the build. Furthermore, for builds that don't run on the Hudson continuous integration tool, the class adds the build time to the system property `javafx.runtime.version`. >> >> 2. Modification times >> >> The JAR, JMOD, and ZIP archives store the modification time of each file. >> >> 3. File ordering >> >> The JAR, JMOD, and ZIP archives store their files in the order returned by the file system. The native shared libraries also store their object files in the order returned by the file system. Most file systems, though, do not guarantee the order of a directory's file listing. >> >> 4. Build path >> >> The class `com.sun.javafx.css.parser.Css2Bin` in the JavaFX Graphics module stores the absolute path of its `.css` input file in the corresponding `.bss` output file, which is then included in the JavaFX Controls module. >> >> This pull request modifies the Gradle and Groovy build files to fix the first three sources of non-determinism. A later pull request can modify the Java files to fix the fourth. >> >> [1]: https://reproducible-builds.org/docs/source-date-epoch/ >> [2]: https://salsa.debian.org/reproducible-builds/strip-nondeterminism > > John Neffenger has updated the pull request incrementally with one additional commit since the last revision: > > Revert format of timestamp in version OPT field I reverted the version timestamp to the original format. The version looks like this for "release" early-access builds: $ cat build5/sdk/lib/javafx.properties javafx.version=21-ea javafx.runtime.version=21-ea+12 javafx.runtime.build=12 and like this for developer builds: $ cat build1/sdk/lib/javafx.properties javafx.version=21-internal javafx.runtime.version=21-internal+0-2023-04-06-232926 javafx.runtime.build=0 The only difference is that the timestamp is localized to UTC, while before it was in the local time of the build machine. The `jmod --date` option requires the ISO 8601 extended format, so we need at least two different formats for the timestamp. Meanwhile, Java has no built-in support for parsing an ISO 8601 string in basic format, so both the current non-standard format and the standard basic format need a `DateTimeFormatter` with a custom pattern. There's no advantage from a parsing perspective in using the standard format: // Parses the format in the current JavaFX release var currentFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HHmmss"); var localTime = LocalDateTime.parse(timestamp, currentFormatter); // Parses the ISO 8601 basic format var basicFormatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX"); var zonedTime = ZonedDateTime.parse(timestamp, basicFormatter); ------------- PR Comment: https://git.openjdk.org/jfx/pull/446#issuecomment-1499982010 From jhendrikx at openjdk.org Fri Apr 7 06:36:50 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Fri, 7 Apr 2023 06:36:50 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: References: Message-ID: > Description copied from issue: > > There are up to two additional invalidations performed that really should be avoided, causing downstream fluent bindings to be recomputed with the same values. This is very confusing as these should only be called when there is an actual change, and not called for the same value multiple times in a row. > > These two extra invalidations have two different causes, each causing an additional invalidation to be triggered: > > 1) ObjectBinding's `isObserved` is delayed slightly. When you add a listener, the listener is added internally and the binding is made valid; this triggers some downstream activity which checks the `isObserved` status to decide whether to start observation of properties -- unfortunately this still returns `false` at that time. A work-around for this existed by calling `getValue` again in `LazyObjectBinding` with a huge comment explaining why this is needed. Although this works, it still means that a downstream function like `map` is called an additional time while it should really only be called once. > > The solution is to ensure `isObserved` returns `true` before the `ExpressionHelper` is called. Already verified this solves the problem. This also means the work-around in `LazyObjectBinding` is no longer needed, which seems like a big win. > > 2) The second additional call originates from a different issue. When `ConditionalBinding` (which implements the `when` construct) sees its condition property changing, it always invalidates itself. This is however only necessary if the current cached value (if it was valid) differs from the current source value. To prevent an unnecessary invalidation, and the resulting revalidation calls that this will trigger, a simple check to see if the value actually changed before invalidating solves this problem. John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Fix review comments ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1056/files - new: https://git.openjdk.org/jfx/pull/1056/files/cda2e6ec..33bb5691 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1056&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1056&range=00-01 Stats: 31 lines in 2 files changed: 25 ins; 0 del; 6 mod Patch: https://git.openjdk.org/jfx/pull/1056.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1056/head:pull/1056 PR: https://git.openjdk.org/jfx/pull/1056 From jhendrikx at openjdk.org Fri Apr 7 06:36:52 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Fri, 7 Apr 2023 06:36:52 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 17:35:05 GMT, Michael Strau? wrote: > Looks good to me. @mstr2 Thanks, solved your review comments ------------- PR Comment: https://git.openjdk.org/jfx/pull/1056#issuecomment-1499985346 From jvos at openjdk.org Fri Apr 7 08:18:00 2023 From: jvos at openjdk.org (Johan Vos) Date: Fri, 7 Apr 2023 08:18:00 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 22:30:45 GMT, Kevin Rushforth wrote: > @johanvos You might want to take a look at this, since it supersedes your earlier PR #547. It also supersedes #553 ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1500058222 From jvos at openjdk.org Fri Apr 7 08:35:54 2023 From: jvos at openjdk.org (Johan Vos) Date: Fri, 7 Apr 2023 08:35:54 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v10] In-Reply-To: References: Message-ID: <62ZJxU4t-HX2a3PZDifV0xrZRQlrPMORk6NiQcTDyEo=.e5f923be-d686-4648-b730-e7f42b2c2a42@github.com> On Tue, 4 Apr 2023 21:16:49 GMT, Phil Race wrote: >> modules/javafx.graphics/src/main/java/com/sun/javafx/font/coretext/CTGlyphLayout.java line 83: >> >>> 81: if (fr == null) return -1; >>> 82: slot = fr.getSlotForFont(fontName); >>> 83: if (slot == -1) { >> >> minor: may be `< 0`? > > We should never have -2 etc. If we do, then the code will fail and we'd know about it I noticed checks on either `slot >= 0` or `slot == -1` and was thinking about it as well. But I agree with @prrace , there is not an assignment that could legally result in -2. If that happens, it would be a major failure and we can't pretend it is the same as -1. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1160541854 From jvos at openjdk.org Fri Apr 7 08:40:02 2023 From: jvos at openjdk.org (Johan Vos) Date: Fri, 7 Apr 2023 08:40:02 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v10] In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 20:17:15 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > Fix formatting and NPE modules/javafx.graphics/src/main/java/com/sun/javafx/font/PrismFontFactory.java line 243: > 241: /* > 242: * macOS: we need to load unique fonts for regular and bold. > 243: * Probably this should be handled elsewhere This indeed adds macos specific behavior in an otherwise OS-neutral concept, but I don't see a simple approach where the key is calculated in an OS-specific approach without introducing artificial overhead. So I am ok with doing this here. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1067#discussion_r1160544238 From jvos at openjdk.org Fri Apr 7 08:45:55 2023 From: jvos at openjdk.org (Johan Vos) Date: Fri, 7 Apr 2023 08:45:55 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS [v10] In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 20:17:15 GMT, Phil Race wrote: >> This PR addresses some font problems on macOS. >> (1) Garbled Arabic with the System font >> (2) Non-ideal fallback fonts for all fonts >> (3) No bold for System font. >> >> In particular the standard System Font was garbling Arabic text - random glyphs from another font. >> The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from >> enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract >> the name from the core text font loaded by that special API. >> These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" >> and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" >> and "SFArabic.ttf" and similar. >> >> JavaFX has its own "System" font family logical name and in order to map to the macOS system font, >> several releases ago we started using the special API referenced above. >> >> Normally we have our own list of fall back fonts for other scripts. >> But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, >> it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds >> this new font to its fallback list - by name. >> But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. >> >> So to fix this we need to grab the reference to the font that was returned by CoreText and use >> that to create the PrismFont we add as a fall back. >> The code that first recognises it needs to go this route is in CTGlyphLayout.java when >> "getSlotForFont(String name") fails. >> Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. >> There's also supporting changes in native code - coretext.c >> >> Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, >> we need to make some more changes >> Now on to more "fallback" enhancements. >> Prior to this fix, on macOS we had a short, hard-coded global list. >> This fix calls the macOS API to get the cascading fallback list for a font. >> This improves the fallback behaviour in respect to providing >> (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. >> There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from >> "if else if else in shared code, down into the appropriate platform factory >> >> This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the >> native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes >> were made to follow it. >> In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" >> file name. Without being able to identify the file we aren't able to use the font to skip them. >> More changes would be needed to provide a PrismFont subclass that can handle this case. >> Fortunately that isn't happening for any of the fallbacks we get from complex text layout. >> >> The final thing this fixes is that "System Bold" was the same as "System Regular". >> The needed name getting lost along the way to constructing the native font. >> >> The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. >> And some day after that we could expose API that allows apps to request non-named variations. > > Phil Race has updated the pull request incrementally with one additional commit since the last revision: > > Fix formatting and NPE Marked as reviewed by jvos (Reviewer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1067#pullrequestreview-1375982480 From jvos at openjdk.org Fri Apr 7 08:45:57 2023 From: jvos at openjdk.org (Johan Vos) Date: Fri, 7 Apr 2023 08:45:57 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Fri, 7 Apr 2023 08:15:08 GMT, Johan Vos wrote: >> @johanvos You might want to take a look at this, since it supersedes your earlier PR #547. > >> @johanvos You might want to take a look at this, since it supersedes your earlier PR #547. > > It also supersedes #553 > @johanvos did you have any comments on this PR? This approach is a much better approach to fix PR #547 and PR #553 I had a high-level look at the diff, and it is clean and understandable (also, great explanation in the description of the PR, that really helps in understanding the PR!). I added one comment about the macos-specific test in PrismFontFactory, but I think the proposed solution is the most elegant approach to match the macos concepts to the JavaFX concepts. I checked the previous review comments and the replies, all looking good. @jperedadnr did some UI tests, and we see the major improvements as well. Excellent work! ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1500078466 From mstrauss at openjdk.org Fri Apr 7 11:37:49 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Fri, 7 Apr 2023 11:37:49 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: References: Message-ID: On Fri, 7 Apr 2023 06:36:50 GMT, John Hendrikx wrote: >> Description copied from issue: >> >> There are up to two additional invalidations performed that really should be avoided, causing downstream fluent bindings to be recomputed with the same values. This is very confusing as these should only be called when there is an actual change, and not called for the same value multiple times in a row. >> >> These two extra invalidations have two different causes, each causing an additional invalidation to be triggered: >> >> 1) ObjectBinding's `isObserved` is delayed slightly. When you add a listener, the listener is added internally and the binding is made valid; this triggers some downstream activity which checks the `isObserved` status to decide whether to start observation of properties -- unfortunately this still returns `false` at that time. A work-around for this existed by calling `getValue` again in `LazyObjectBinding` with a huge comment explaining why this is needed. Although this works, it still means that a downstream function like `map` is called an additional time while it should really only be called once. >> >> The solution is to ensure `isObserved` returns `true` before the `ExpressionHelper` is called. Already verified this solves the problem. This also means the work-around in `LazyObjectBinding` is no longer needed, which seems like a big win. >> >> 2) The second additional call originates from a different issue. When `ConditionalBinding` (which implements the `when` construct) sees its condition property changing, it always invalidates itself. This is however only necessary if the current cached value (if it was valid) differs from the current source value. To prevent an unnecessary invalidation, and the resulting revalidation calls that this will trigger, a simple check to see if the value actually changed before invalidating solves this problem. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Fix review comments Marked as reviewed by mstrauss (Committer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1056#pullrequestreview-1376116225 From kcr at openjdk.org Fri Apr 7 12:03:55 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Fri, 7 Apr 2023 12:03:55 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Fri, 7 Apr 2023 08:43:14 GMT, Johan Vos wrote: >>> @johanvos You might want to take a look at this, since it supersedes your earlier PR #547. >> >> It also supersedes #553 > >> @johanvos did you have any comments on this PR? > > This approach is a much better approach to fix PR #547 and PR #553 > I had a high-level look at the diff, and it is clean and understandable (also, great explanation in the description of the PR, that really helps in understanding the PR!). > I added one comment about the macos-specific test in PrismFontFactory, but I think the proposed solution is the most elegant approach to match the macos concepts to the JavaFX concepts. > I checked the previous review comments and the replies, all looking good. > > @jperedadnr did some UI tests, and we see the major improvements as well. > Excellent work! > > @johanvos You might want to take a look at this, since it supersedes your earlier PR #547. > > It also supersedes #553 Oh, good. In that case, once Phil integrates this PR, PRs #547 and #553 can be closed, and [JDK-8269593](https://bugs.openjdk.org/browse/JDK-8269593) can be closed as a duplicate of [JDK-8246104](https://bugs.openjdk.org/browse/JDK-8246104). ------------- PR Comment: https://git.openjdk.org/jfx/pull/1067#issuecomment-1500224267 From kcr at openjdk.org Fri Apr 7 12:39:55 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Fri, 7 Apr 2023 12:39:55 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 13:03:04 GMT, Karthik P K wrote: > When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. > > Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. > > Added system test to validate the fix. @andy-goryachev-oracle can you also review this? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1082#issuecomment-1500252211 From kcr at openjdk.org Fri Apr 7 12:46:50 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Fri, 7 Apr 2023 12:46:50 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu In-Reply-To: References: Message-ID: <3uhYcztlAsED-fDKxnQYhl3swizxXHVr1cX5S2TRf7A=.9003e826-0332-4bd8-8d41-f852fe3bb78f@github.com> On Thu, 6 Apr 2023 13:03:04 GMT, Karthik P K wrote: > When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. > > Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. > > Added system test to validate the fix. Andy and Ajit can formally review this, but I do have one quick minor comment. The test skin is in the package `test.robot.javafx.customSkins`, which doesn't match our code convention of using all lower-case letters for package names. I recommend changing this (meaning you will also need to rename the directory). ------------- PR Comment: https://git.openjdk.org/jfx/pull/1082#issuecomment-1500256917 From jvos at openjdk.org Fri Apr 7 14:02:08 2023 From: jvos at openjdk.org (Johan Vos) Date: Fri, 7 Apr 2023 14:02:08 GMT Subject: RFR: 8260528: Clean glass-gtk sizing and positioning code [v56] In-Reply-To: References: <5-LHfl6_vdrmRjLivevBopnWBbzgO0ygK1dRPAFdzoM=.22e09b72-4142-4c1c-b320-94a1c48aaa69@github.com> Message-ID: On Sun, 2 Apr 2023 20:49:38 GMT, Thiago Milczarek Sayao wrote: >> This cleans size and positioning code, reducing special cases, code complexity and size. >> >> Changes: >> >> - cached extents: 28, 1, 1, 1 are old defaults - modern gnome uses different sizes. It does not assume any size because it varies - it does cache because it's unlikely to vary on the same system - but if it does occur, it will only waste a resize event. >> - window geometry, min/max size are centralized in `update_window_constraints`; >> - Frame extents (the window decoration size used for "total window size"): >> - frame extents are received in `process_property_notify`; >> - removed quirks in java code; >> - When received, call `set_bounds` again to adjust the size (to account decorations later received); >> - Removed `activate_window` because it's the same as focusing the window. `gtk_window_present` will deiconify and focus it. >> - `ensure_window_size` was a quirk - removed; >> - `requested_bounds` removed - not used anymore; >> - `window_configure` incorporated in `set_bounds` with `gtk_window_move` and `gtk_window_resize`; >> - `process_net_wm_property` is a work-around for Unity only (added a check if Unity - but it can probably be removed at some point) >> - `restack` split in `to_front()` and `to_back()` to conform to managed code; > > Thiago Milczarek Sayao has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 78 commits: > > - Merge branch 'master' into clean_glass_gtk > - Merge branch 'openjdk:master' into master > - Merge branch 'openjdk:master' into master > - Merge branch 'openjdk:master' into master > - Merge branch 'openjdk:master' into master > - Fix bug when window starts maximized and restores to wrong size > - Minor adjustments > - Fix window order > - Revert "Fix window order (focus event)" > > This reverts commit 1ab609906e48ed8fb1b6f229c3afc0d4d2b79472. > - Fix window order (focus event) > - ... and 68 more: https://git.openjdk.org/jfx/compare/c23d067d...89e4efc6 I looked at the diffs, and re-did my tests. All working as expected on Ubuntu 22.04. ------------- Marked as reviewed by jvos (Reviewer). PR Review: https://git.openjdk.org/jfx/pull/915#pullrequestreview-1376228903 From jgneff at openjdk.org Fri Apr 7 16:08:00 2023 From: jgneff at openjdk.org (John Neffenger) Date: Fri, 7 Apr 2023 16:08:00 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v13] In-Reply-To: <_WXDVDoiGezrJmltUlcPkKflohZhoWjwjYQedH93PIE=.65682e52-8f40-47f3-8cfd-ce0251ebac97@github.com> References: <_WXDVDoiGezrJmltUlcPkKflohZhoWjwjYQedH93PIE=.65682e52-8f40-47f3-8cfd-ce0251ebac97@github.com> Message-ID: On Fri, 7 Apr 2023 06:22:05 GMT, John Neffenger wrote: >> This pull request allows for reproducible builds of JavaFX on Linux, macOS, and Windows by defining the `SOURCE_DATE_EPOCH` environment variable. For example, the following commands create a reproducible build: >> >> >> $ export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) >> $ bash gradlew sdk jmods javadoc >> $ strip-nondeterminism -v -T $SOURCE_DATE_EPOCH build/jmods/*.jmod >> >> >> The three commands: >> >> 1. set the build timestamp to the date of the latest source code change, >> 2. build the JavaFX SDK libraries, JMOD archives, and API documentation, and >> 3. recreate the JMOD files with stable file modification times and ordering. >> >> The third command won't be necessary once Gradle can build the JMOD archives or the `jmod` tool itself has the required support. For more information on the environment variable, see the [`SOURCE_DATE_EPOCH`][1] page. For more information on the command to recreate the JMOD files, see the [`strip-nondeterminism`][2] repository. I'd like to propose that we allow for reproducible builds in JavaFX 17 and consider making them the default in JavaFX 18. >> >> #### Fixes >> >> There are at least four sources of non-determinism in the JavaFX builds: >> >> 1. Build timestamp >> >> The class `com.sun.javafx.runtime.VersionInfo` in the JavaFX Base module stores the time of the build. Furthermore, for builds that don't run on the Hudson continuous integration tool, the class adds the build time to the system property `javafx.runtime.version`. >> >> 2. Modification times >> >> The JAR, JMOD, and ZIP archives store the modification time of each file. >> >> 3. File ordering >> >> The JAR, JMOD, and ZIP archives store their files in the order returned by the file system. The native shared libraries also store their object files in the order returned by the file system. Most file systems, though, do not guarantee the order of a directory's file listing. >> >> 4. Build path >> >> The class `com.sun.javafx.css.parser.Css2Bin` in the JavaFX Graphics module stores the absolute path of its `.css` input file in the corresponding `.bss` output file, which is then included in the JavaFX Controls module. >> >> This pull request modifies the Gradle and Groovy build files to fix the first three sources of non-determinism. A later pull request can modify the Java files to fix the fourth. >> >> [1]: https://reproducible-builds.org/docs/source-date-epoch/ >> [2]: https://salsa.debian.org/reproducible-builds/strip-nondeterminism > > John Neffenger has updated the pull request incrementally with one additional commit since the last revision: > > Revert format of timestamp in version OPT field For the record, here's the latest version of my program that tests the timestamp formats: import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; public class Timestamp { private static final String OPT = "([-a-zA-Z0-9.]+)"; private static final String OK = " (OK)"; private static final String NOT_OK = " (FAILED)"; public static void main(String[] args) { var buildInstant = Instant.now().truncatedTo(ChronoUnit.SECONDS); // Creates the timestamp in the ISO 8601 extended format String extended = buildInstant.toString(); // Creates the timestamp in the current non-stnadard format var zonedTime = ZonedDateTime.ofInstant(buildInstant, ZoneOffset.UTC); var currentFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HHmmss"); String current = zonedTime.format(currentFormatter); // Creates the timestamp in the ISO 8601 basic format zonedTime = ZonedDateTime.ofInstant(buildInstant, ZoneOffset.UTC); var basicFormatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssX"); String basic = zonedTime.format(basicFormatter); // Prints the timestamps and checks them for the version OPT field System.out.print("ISO 8601 extended format = " + extended); System.out.println(extended.matches(OPT) ? OK : NOT_OK); System.out.print("Current JavaFX format = " + current); System.out.println(current.matches(OPT) ? OK : NOT_OK); System.out.print("ISO 8601 basic format = " + basic); System.out.println(basic.matches(OPT) ? OK : NOT_OK); System.out.println(); // Parses the timestamp in the ISO 8601 extended format zonedTime = ZonedDateTime.parse(extended); System.out.println("Parsed extended time = " + zonedTime); // Parses the timestamp in the current non-standard format var localTime = LocalDateTime.parse(current, currentFormatter); System.out.println("Parsed current time = " + localTime); // Parses the timestamp in the ISO 8601 basic format zonedTime = ZonedDateTime.parse(basic, basicFormatter); System.out.println("Parsed basic time = " + zonedTime); } } Below is a sample of its output: $ java Timestamp ISO 8601 extended format = 2023-04-07T16:01:16Z (FAILED) Current JavaFX format = 2023-04-07-160116 (OK) ISO 8601 basic format = 20230407T160116Z (OK) Parsed extended time = 2023-04-07T16:01:16Z Parsed current time = 2023-04-07T16:01:16 Parsed basic time = 2023-04-07T16:01:16Z ------------- PR Comment: https://git.openjdk.org/jfx/pull/446#issuecomment-1500420915 From prr at openjdk.org Fri Apr 7 17:01:59 2023 From: prr at openjdk.org (Phil Race) Date: Fri, 7 Apr 2023 17:01:59 GMT Subject: Integrated: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: References: Message-ID: On Fri, 24 Mar 2023 21:37:16 GMT, Phil Race wrote: > This PR addresses some font problems on macOS. > (1) Garbled Arabic with the System font > (2) Non-ideal fallback fonts for all fonts > (3) No bold for System font. > > In particular the standard System Font was garbling Arabic text - random glyphs from another font. > The root of this issue is that several releases ago macOS introduced UI fonts that are hidden from > enumeration. must be loaded by a special API and cannot be loaded by name, even if you extract > the name from the core text font loaded by that special API. > These fonts usually have a name that begins with "." such as the postscript name ".AppleUISystemFont" > and "name" for the main instance of this will be "System Font Regular". These live in files called "SFNS.ttf" > and "SFArabic.ttf" and similar. > > JavaFX has its own "System" font family logical name and in order to map to the macOS system font, > several releases ago we started using the special API referenced above. > > Normally we have our own list of fall back fonts for other scripts. > But when we encounter complex scripts such as Arabic, and ask CoreText to layout the glyphs, > it may use other system fonts for Arabic (eg ".SFArabic") and the FX code dynamically adds > this new font to its fallback list - by name. > But this new font can't be directly referenced by name either, but that's what used to work and the FX code tries. > > So to fix this we need to grab the reference to the font that was returned by CoreText and use > that to create the PrismFont we add as a fall back. > The code that first recognises it needs to go this route is in CTGlyphLayout.java when > "getSlotForFont(String name") fails. > Instead it calls new code in CTFactory which in turn calls a new constructor and supporting code in CTFontFile.java. > There's also supporting changes in native code - coretext.c > > Additionally to support that when we ask the platform to enumerate fallbacks, we might get such "." fonts, > we need to make some more changes > Now on to more "fallback" enhancements. > Prior to this fix, on macOS we had a short, hard-coded global list. > This fix calls the macOS API to get the cascading fallback list for a font. > This improves the fallback behaviour in respect to providing > (1) More appropriate styles, (2) More supported code pointd, (3) Code point support coming from a preferred font. > There was some desirable re-factoring as part of this, as the location of fallbacks was pushed from > "if else if else in shared code, down into the appropriate platform factory > > This also made it easier to do some required changes to allow fallbacks to be pre-initialised with the > native font resource, not just a name+ file. The new class FontFallbackInfo encapsulates this and changes > were made to follow it. > In practice on macOS it seems that some "." cascading fallbacks for the "." system font come with a "NULL" > file name. Without being able to identify the file we aren't able to use the font to skip them. > More changes would be needed to provide a PrismFont subclass that can handle this case. > Fortunately that isn't happening for any of the fallbacks we get from complex text layout. > > The final thing this fixes is that "System Bold" was the same as "System Regular". > The needed name getting lost along the way to constructing the native font. > > The work done here also highlighted that we really need to add code that at least recognises OpenType variation fonts. > And some day after that we could expose API that allows apps to request non-named variations. This pull request has now been integrated. Changeset: a1add2e3 Author: Phil Race URL: https://git.openjdk.org/jfx/commit/a1add2e3d5525e0fbc7a44e252a1b5323972455d Stats: 934 lines in 21 files changed: 705 ins; 155 del; 74 mod 8246104: Some complex text doesn't render correctly on macOS Reviewed-by: angorya, kcr, jvos ------------- PR: https://git.openjdk.org/jfx/pull/1067 From duke at openjdk.org Fri Apr 7 17:19:56 2023 From: duke at openjdk.org (Martin Fox) Date: Fri, 7 Apr 2023 17:19:56 GMT Subject: RFR: 8278938: [Win] Robot can target wrong key for punctuation and symbols [v3] In-Reply-To: References: Message-ID: > When processing a `WM_CHAR` event on an OEM key (punctuation, symbol, dead key) the glass code will dynamically query the key's unshifted character to determine the Java code to assign to it. This is necessary since the relationship between OEM key codes and the characters they generate varies from layout to layout. > > The Robot implementation was consulting a table which assumed a fixed relationship between Java codes and Windows key codes even for the OEM keys. The table was also missing entries for any Java code not on a US QWERTY layout, like PLUS. > > In this PR if we don't find the Java code in the table or if it maps to an OEM key (which may be wrong) we sweep through all the OEM keys looking for the matching Java code. Martin Fox has updated the pull request incrementally with one additional commit since the last revision: Updated license header copyrights ------------- Changes: - all: https://git.openjdk.org/jfx/pull/702/files - new: https://git.openjdk.org/jfx/pull/702/files/e9dfaa75..d0d7acab Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=702&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=702&range=01-02 Stats: 3 lines in 3 files changed: 0 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jfx/pull/702.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/702/head:pull/702 PR: https://git.openjdk.org/jfx/pull/702 From duke at openjdk.org Fri Apr 7 18:30:52 2023 From: duke at openjdk.org (Martin Fox) Date: Fri, 7 Apr 2023 18:30:52 GMT Subject: RFR: 8278938: [Win] Robot can target wrong key for punctuation and symbols [v2] In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 11:48:58 GMT, Jose Pereda wrote: > I wonder if RobotKeySanityTest could be part of the PR as a manual test? Same as in #694 The RobotKeySanityTest is tricky, it requires the user to press a lot of keys to get good coverage but can produce confusing results if the user presses certain keys, like AltGr. Windows treats AltGr as if you pressed Ctrl and Alt at the same time. This means the OS sends two events when you press the key and two more when you release it. This is confusing the RobotKeySanityTest which can only handle one press/release pair at a time. I'm not sure I can fix the test but will think about it. The KeyboardTest app that I recently added to PR #425 covers most of the same ground and avoids the problematic keys. The downside of KeyboardTest is that it only provides good coverage for specific layouts (I'll try to add Spanish) and provides the best coverage when run against multiple layouts which takes effort to set up. I've written an app that just logs key events as the user types and that would probably be a better candidate to attach to some PR. When something confusing happens with RobotKeySanityTest or KeyboardTest that's the app I pull up to diagnose what's going on (like I just did with AltGr). ------------- PR Comment: https://git.openjdk.org/jfx/pull/702#issuecomment-1500530373 From jpereda at openjdk.org Fri Apr 7 19:20:55 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Fri, 7 Apr 2023 19:20:55 GMT Subject: RFR: 8278938: [Win] Robot can target wrong key for punctuation and symbols [v3] In-Reply-To: References: Message-ID: <-g3d777YhFVA26vIYWYGDNSjHKcYsw99l2fLOPgLiBg=.f54e6177-bf03-40a5-b09f-f52ce65662f3@github.com> On Fri, 7 Apr 2023 17:19:56 GMT, Martin Fox wrote: >> When processing a `WM_CHAR` event on an OEM key (punctuation, symbol, dead key) the glass code will dynamically query the key's unshifted character to determine the Java code to assign to it. This is necessary since the relationship between OEM key codes and the characters they generate varies from layout to layout. >> >> The Robot implementation was consulting a table which assumed a fixed relationship between Java codes and Windows key codes even for the OEM keys. The table was also missing entries for any Java code not on a US QWERTY layout, like PLUS. >> >> In this PR if we don't find the Java code in the table or if it maps to an OEM key (which may be wrong) we sweep through all the OEM keys looking for the matching Java code. > > Martin Fox has updated the pull request incrementally with one additional commit since the last revision: > > Updated license header copyrights Looks good! Okay, makes sense. I'll approve this PR as is then, if you modify it for any reason, I'll review again. ------------- Marked as reviewed by jpereda (Reviewer). PR Review: https://git.openjdk.org/jfx/pull/702#pullrequestreview-1376508988 PR Comment: https://git.openjdk.org/jfx/pull/702#issuecomment-1500569428 From kcr at openjdk.org Fri Apr 7 20:33:53 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Fri, 7 Apr 2023 20:33:53 GMT Subject: RFR: 8087370: [odroid] Monocle: Touch is still broken on Odroid In-Reply-To: <8r1cERIcJeZVLWYcG3EqWV7zKEoDqtLLgqBVHlPIUyI=.9f7e72c8-de1a-49f6-9df2-8d6a5f46174a@github.com> References: <8r1cERIcJeZVLWYcG3EqWV7zKEoDqtLLgqBVHlPIUyI=.9f7e72c8-de1a-49f6-9df2-8d6a5f46174a@github.com> Message-ID: <0fVh4l6AwpUCk4H2p3uSAGkdLqB_j0y4wzCihYUrEWA=.a95ea8b9-f576-405b-9971-758abe1eb95e@github.com> On Wed, 13 Oct 2021 10:52:40 GMT, Fabian Wolter wrote: > There are sometimes multitouch events detected, when only a single touch should be detected under certain conditions. This lead to touch events on previous touch positions. > > The referenced bug is closed with "won't fix" with the justification it would be platform specific. But this is not correct. It affects all Linux platforms combined with a touch controller, which sends the touch events in an uncommon, but valid(!), order. > > We encountered this problem with the touch controller ILI2511 with firmware V6000_V1 in the Tianma display TM070JVHG33. This patch fixes the problem. It is the same patch attached to above bug report. I reopened the JBS bug (it has been closed as "Won't fix" long ago). @johanvos or @jperedadnr can decide whether they want to review and sponsor this. ------------- PR Comment: https://git.openjdk.org/jfx/pull/641#issuecomment-1500617906 From kcr at openjdk.org Fri Apr 7 21:04:01 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Fri, 7 Apr 2023 21:04:01 GMT Subject: RFR: 8264449: Enable reproducible builds with SOURCE_DATE_EPOCH [v13] In-Reply-To: <_WXDVDoiGezrJmltUlcPkKflohZhoWjwjYQedH93PIE=.65682e52-8f40-47f3-8cfd-ce0251ebac97@github.com> References: <_WXDVDoiGezrJmltUlcPkKflohZhoWjwjYQedH93PIE=.65682e52-8f40-47f3-8cfd-ce0251ebac97@github.com> Message-ID: <5ZJd3raMv-JHrV3hPknuU6mHzAyORs9g-SVklJ0ksCY=.630de30b-c0a4-4897-9dd8-187f2485eea2@github.com> On Fri, 7 Apr 2023 06:22:05 GMT, John Neffenger wrote: >> This pull request allows for reproducible builds of JavaFX on Linux, macOS, and Windows by defining the `SOURCE_DATE_EPOCH` environment variable. For example, the following commands create a reproducible build: >> >> >> $ export SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) >> $ bash gradlew sdk jmods javadoc >> $ strip-nondeterminism -v -T $SOURCE_DATE_EPOCH build/jmods/*.jmod >> >> >> The three commands: >> >> 1. set the build timestamp to the date of the latest source code change, >> 2. build the JavaFX SDK libraries, JMOD archives, and API documentation, and >> 3. recreate the JMOD files with stable file modification times and ordering. >> >> The third command won't be necessary once Gradle can build the JMOD archives or the `jmod` tool itself has the required support. For more information on the environment variable, see the [`SOURCE_DATE_EPOCH`][1] page. For more information on the command to recreate the JMOD files, see the [`strip-nondeterminism`][2] repository. I'd like to propose that we allow for reproducible builds in JavaFX 17 and consider making them the default in JavaFX 18. >> >> #### Fixes >> >> There are at least four sources of non-determinism in the JavaFX builds: >> >> 1. Build timestamp >> >> The class `com.sun.javafx.runtime.VersionInfo` in the JavaFX Base module stores the time of the build. Furthermore, for builds that don't run on the Hudson continuous integration tool, the class adds the build time to the system property `javafx.runtime.version`. >> >> 2. Modification times >> >> The JAR, JMOD, and ZIP archives store the modification time of each file. >> >> 3. File ordering >> >> The JAR, JMOD, and ZIP archives store their files in the order returned by the file system. The native shared libraries also store their object files in the order returned by the file system. Most file systems, though, do not guarantee the order of a directory's file listing. >> >> 4. Build path >> >> The class `com.sun.javafx.css.parser.Css2Bin` in the JavaFX Graphics module stores the absolute path of its `.css` input file in the corresponding `.bss` output file, which is then included in the JavaFX Controls module. >> >> This pull request modifies the Gradle and Groovy build files to fix the first three sources of non-determinism. A later pull request can modify the Java files to fix the fourth. >> >> [1]: https://reproducible-builds.org/docs/source-date-epoch/ >> [2]: https://salsa.debian.org/reproducible-builds/strip-nondeterminism > > John Neffenger has updated the pull request incrementally with one additional commit since the last revision: > > Revert format of timestamp in version OPT field Your solution using two formatted date strings looks good to me. Thanks for the additional detail. ------------- PR Comment: https://git.openjdk.org/jfx/pull/446#issuecomment-1500643246 From kcr at openjdk.org Fri Apr 7 21:46:50 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Fri, 7 Apr 2023 21:46:50 GMT Subject: RFR: JDK-8304959: Public API in javafx.css.Match should not return private API class PseudoClassState In-Reply-To: References: <-zNr6tpAvHM6uPLbSIoSdws0ASyWrg6U_LJf4R5FTTY=.5f540c9b-4f7c-47ed-9321-61b2c804181d@github.com> Message-ID: On Fri, 31 Mar 2023 13:24:27 GMT, Kevin Rushforth wrote: >> The CSS API baffles me a bit. It doesn't seem consistent. >> >> Just now I took a look at the class `SimpleSelector` and `CompoundSelector`. These are public, yet cannot be constructed by users. They're also not returned anywhere (the closest is `Selector#createSelector` which returns the interface). >> >> Essentially this means that `SimpleSelector` and `CompoundSelector` should probably be package private. Yet, I guess they were made public because `SelectorPartitioning` is doing instanceof checks and is casting to these classes. But anybody can do that now, and that means that for example `SimpleSelector#getStyleClassSet` is exposed, which returns a mutable set... >> >> Reading between the lines though it seems that `SimpleSelector` and `CompoundSelector` were intended to be fully immutable (which makes sense as they represent a style sheet). Any changes would not be picked up as nothing is observing these properties. >> >> I think these loopholes should be closed. >> >> There are two options IMHO: >> >> 1. Move `SimpleSelector` and `CompoundSelector` to the com hierarchy. They can't be publically constructed, and are never returned. The only way to reach them is by casting. >> 2. If it's too late for that, then close all loopholes and ensure that these two classes are fully immutable. From what I can see now, only `getStyleClassSet` and the mentioned method in `Match` need closing. `CompoundSelector` is already immutable. > > I'll take a closer look early next week. > I think that Match is supposed to be immutable, given the non-public constructor. Match itself will never change the set (and nothing else will) so making it observable seems unnecessary. Agreed. > In other words, simpleSelector.createMatch().getPseudoClasses().clear() would break the Selectors encapsulation. > > I think it's best to close that loophole. If you agree, I can document this method that it returns an immutable set, which is also what I assumed would be the case in my other PR where I made many of these immutable. Yes, this seems like the best solution to me. > Essentially this means that SimpleSelector and CompoundSelector should probably be package private. I agree that these two classes should not have been made public when the javafx.css package was created as public API back in JDK 9. The usual process for removing API is to deprecate it for removal in one release and then remove it in a future release, but in this case, since those classes cannot be constructed, and are never returned by any public API, any use of them would be relying on an implementation detail (via an `instanceof` and a cast, to no good purpose). Since there is no useful way an application could be using these classes, I recommend option 1, as long as those two classes can be cleanly moved to com.sun.javafx.css. Otherwise, we could go with option 2 along with deprecating those two classes for removal. The Specification section of the CSR would simply propose to remove those two classes. You could describe what is happening (moving them to a non-exported package) in the Solution section. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1070#discussion_r1160981604 From kcr at openjdk.org Fri Apr 7 21:56:52 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Fri, 7 Apr 2023 21:56:52 GMT Subject: RFR: JDK-8224260: ChangeListener not triggered when adding a new listener in invalidated method In-Reply-To: References: Message-ID: On Thu, 30 Mar 2023 21:53:48 GMT, John Hendrikx wrote: > Fixes three issues in ExpressionHelper: > > - Current Value was not retained when changing from SingleChange to Generic, this can lead to missed changes > - Current Value was not retained when changing from Generic to SingleChange, this can lead to missed changes > - Current Value was not cleared when last change listener was removed in Generic variant, resulting in an older value being referenced and not becoming eligible for GC until either a ChangeListener is added again, or sufficient InvalidationListeners are removed to switch to the SingleInvalidation implementation... Looks good. I confirm the new test fails without the fix and passes with the fix. @nlisker would you be willing to also review this? ------------- Marked as reviewed by kcr (Lead). PR Review: https://git.openjdk.org/jfx/pull/1078#pullrequestreview-1376619837 PR Comment: https://git.openjdk.org/jfx/pull/1078#issuecomment-1500676550 From nlisker at openjdk.org Fri Apr 7 22:02:50 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Fri, 7 Apr 2023 22:02:50 GMT Subject: RFR: JDK-8224260: ChangeListener not triggered when adding a new listener in invalidated method In-Reply-To: References: Message-ID: On Thu, 30 Mar 2023 21:53:48 GMT, John Hendrikx wrote: > Fixes three issues in ExpressionHelper: > > - Current Value was not retained when changing from SingleChange to Generic, this can lead to missed changes > - Current Value was not retained when changing from Generic to SingleChange, this can lead to missed changes > - Current Value was not cleared when last change listener was removed in Generic variant, resulting in an older value being referenced and not becoming eligible for GC until either a ChangeListener is added again, or sufficient InvalidationListeners are removed to switch to the SingleInvalidation implementation... Yes. I'm in the middle of reviewing another PR, so this will be the next one. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1078#issuecomment-1500679355 From kcr at openjdk.org Fri Apr 7 22:38:51 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Fri, 7 Apr 2023 22:38:51 GMT Subject: RFR: 8303740 JavaFX - Leak in Logging, Logging remembers last exception [v2] In-Reply-To: References: Message-ID: <45CYzfilVYqeGrXBb8osOh-EWqAWsZARtyOfCysUfRM=.db6a7c32-5aab-40c4-9c20-e5b1eed2ce0c@github.com> On Thu, 23 Mar 2023 08:31:41 GMT, Florian Kirmaier wrote: >> When an exception is logged in JavaFX, then the exception is kept in a reference. >> This way, always the last logged exception is retained. >> >> This is a memory-leak. >> This was done to write unit-tests to ensure certain error-cases are logged. >> >> A simple fix is, to add a flag, to enable/disable retaining the exception. > > Florian Kirmaier has updated the pull request incrementally with one additional commit since the last revision: > > JDK-8303740 > Added changes based on code review Looks good. ------------- Marked as reviewed by kcr (Lead). PR Review: https://git.openjdk.org/jfx/pull/1053#pullrequestreview-1376639795 From tsayao at openjdk.org Fri Apr 7 22:46:49 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Fri, 7 Apr 2023 22:46:49 GMT Subject: RFR: 8278924: [Linux] Robot key test can fail if multiple keyboard layouts are installed In-Reply-To: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> References: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> Message-ID: On Mon, 17 Jan 2022 20:25:08 GMT, Martin Fox wrote: > The Robot implementation on Linux did not consult the current layout when mapping from a KeyCode to a hardware code. Internally it retrieved results for all the layouts but just picked the first one it saw leading to random effects. Though not part of the original bug report, the code also ignored the shift level when choosing which result to pick. On a French layout the dollar sign is on two keys (AltGr 4 is the second one) and the code could choose either one. Same is true for pound. > > This PR consults the current layout and only on shift level 0 which is the same level used in get_glass_key to figure out which KeyCode to assign when generating a KeyEvent. Without the fix: ![image](https://user-images.githubusercontent.com/30704286/230687549-dd2c1212-ae00-4316-b9ad-c9562eb2470f.png) With the fix: ![image](https://user-images.githubusercontent.com/30704286/230687617-ef49355e-3cf0-4093-a737-ed112789517e.png) ------------- PR Comment: https://git.openjdk.org/jfx/pull/718#issuecomment-1500703062 From kcr at openjdk.org Fri Apr 7 22:52:56 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Fri, 7 Apr 2023 22:52:56 GMT Subject: RFR: 8223373: Remove IntelliJ IDEA specific files from the source code repository [v5] In-Reply-To: <3zCUdkkbxcB1NMO9-VFrOgALNGa4k2vC0yXoyqYSbyQ=.596e4f9c-9101-4548-9d7e-134f06d1770c@github.com> References: <3zCUdkkbxcB1NMO9-VFrOgALNGa4k2vC0yXoyqYSbyQ=.596e4f9c-9101-4548-9d7e-134f06d1770c@github.com> Message-ID: On Fri, 3 Mar 2023 01:13:49 GMT, Thiago Milczarek Sayao wrote: >> This PR does: >> >> - Remove specific Idea files and let it be imported from gradle; >> - Adds checkstyle (to use with checkstyle plugin - it will let you know style mistakes); >> - Configures auto-format to sun style (with the changes mentioned in [Code Style Rules](https://wiki.openjdk.org/display/OpenJFX/Code+Style+Rules)); >> - Automatically sets Copyright notice (updates year too); >> - Run configurations for samples/toys and builds. > > Thiago Milczarek Sayao has updated the pull request incrementally with two additional commits since the last revision: > > - Revert "Make intellij see :systemTests dependecies" > > This reverts commit dca7eab24958e1214147b7d291f0faf52ea27ddf. > - Make intellij see :systemTests dependecies > I've reverted the gradle changes, so it pretty much only affect the IDE. Good. I'll let the IntelliJ users do the review. My only comments are on the two files outside the `.idea` directory. .gitignore line 57: > 55: > 56: # IntelliJ > 57: out/ This would pick up more than just IntelliJ files. Are they all needed? .gitignore line 67: > 65: > 66: #mac folder > 67: .DS_Store These seem unrelated to this PR (and in the case of `hs_err`, there is a typo). checkstyle.xml line 1: > 1: I'm not keen on adding yet another top-level file in our repo. Can it go somewhere else? ------------- PR Review: https://git.openjdk.org/jfx/pull/1009#pullrequestreview-1376645064 PR Review Comment: https://git.openjdk.org/jfx/pull/1009#discussion_r1161003425 PR Review Comment: https://git.openjdk.org/jfx/pull/1009#discussion_r1161003615 PR Review Comment: https://git.openjdk.org/jfx/pull/1009#discussion_r1161004078 From tsayao at openjdk.org Fri Apr 7 23:25:53 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Fri, 7 Apr 2023 23:25:53 GMT Subject: RFR: 8278924: [Linux] Robot key test can fail if multiple keyboard layouts are installed In-Reply-To: References: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> Message-ID: <22keOxlQEK5fUTsHqhm6aSxBFQbm9zyg4W27M-B8IdU=.b028c7b9-52f1-48c3-8a82-658ec93828f6@github.com> On Sun, 2 Apr 2023 23:36:27 GMT, Martin Fox wrote: >> @beldenfox Could you point out which tests were failing? >> `test.robot.javafx.embed.swing.SwingNodeJDialogTest` is getting stuck for me. > > @tsayao The best place to start is with the manual test that I added to PR #425 (KeyboardTest.java). That test works on Windows, Mac, and Linux and uses a Robot to throw a whole slew of platform key events at the system and then verify that the right JavaFX KeyEvents come through on the other side. > > The primary motivation for this PR is to pave the way for future PR's. Accelerators involving punctuation and symbols aren't working at all well on Linux (see [JDK-8273743](https://bugs.openjdk.org/browse/JDK-8273743)) and having a working Robot in hand will be extremely helpful in testing the fixes. The manual test in #425 can also be configured to test KeyCharacterCombinations (the component that's broken) but for now you can ignore all that. > > Unfortunately the manual test itself is a big chunk of code that needs to be reviewed but it is the first comprehensive test written for JavaFX keyboard handling. I wish I could make it shorter (it looks more complicated than it is) but the only way to test the keyboard system is to press a lot of keys. > > BTW, the bot that kicked this PR has lousy timing. I'll be out of town for most of the coming week and will be away from my Linux box. @beldenfox I've done some research to understand your code. It seems `gdk_keymap_get_entries_for_keyval` will return multiple entries for hardware keys (as many as the layouts installed). So your change queries which one corresponds to the current layout. It seems correct to me, but I'll leave some suggestions. To observe the problem using pure gdk: #include int main(int argc, char *argv[]) { GdkKeymap *keymap; guint keyval = GDK_KEY_a; // Example keyval guint upper_keyval = gdk_keyval_to_upper(keyval); GdkKeymapKey *keys; gint n_keys; gint group; // Initialize GDK gdk_init(&argc, &argv); // Get the default keymap keymap = gdk_keymap_get_for_display(gdk_display_get_default()); // Get the keycodes for the uppercase character gdk_keymap_get_entries_for_keyval(keymap, upper_keyval, &keys, &n_keys); // Print the keycodes for (int i = 0; i < n_keys; i++) { printf("Keycode: %d\n", keys[i].keycode); } // Free resources g_free(keys); g_object_unref(keymap); return 0; } gcc -o testkey testkey.c `pkg-config --cflags --libs gdk-3.0` ------------- PR Comment: https://git.openjdk.org/jfx/pull/718#issuecomment-1500719003 From tsayao at openjdk.org Fri Apr 7 23:31:50 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Fri, 7 Apr 2023 23:31:50 GMT Subject: RFR: 8278924: [Linux] Robot key test can fail if multiple keyboard layouts are installed In-Reply-To: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> References: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> Message-ID: On Mon, 17 Jan 2022 20:25:08 GMT, Martin Fox wrote: > The Robot implementation on Linux did not consult the current layout when mapping from a KeyCode to a hardware code. Internally it retrieved results for all the layouts but just picked the first one it saw leading to random effects. Though not part of the original bug report, the code also ignored the shift level when choosing which result to pick. On a French layout the dollar sign is on two keys (AltGr 4 is the second one) and the code could choose either one. Same is true for pound. > > This PR consults the current layout and only on shift level 0 which is the same level used in get_glass_key to figure out which KeyCode to assign when generating a KeyEvent. modules/javafx.graphics/src/main/native-glass/gtk/glass_key.cpp line 311: > 309: GdkKeymapKey *keys = nullptr; > 310: gint n_keys = 0; > 311: GdkKeymap* keymap = gdk_keymap_get_default(); ` gdk_keymap_get_for_display(gdk_display_get_default())` is the non deprecated way. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/718#discussion_r1161023161 From tsayao at openjdk.org Sat Apr 8 00:58:57 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sat, 8 Apr 2023 00:58:57 GMT Subject: RFR: 8305768: Unify WindowContext in glass-gtk Message-ID: This unifies and organizes WindowContext of the glass-gtk. It does not change any behaviour, just reorganizes the code. ------------- Commit messages: - Unify WindowContext - Unify window contexts - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - ... and 29 more: https://git.openjdk.org/jfx/compare/0c03a411...b846ed21 Changes: https://git.openjdk.org/jfx/pull/1085/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1085&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8305768 Stats: 1472 lines in 5 files changed: 559 ins; 657 del; 256 mod Patch: https://git.openjdk.org/jfx/pull/1085.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1085/head:pull/1085 PR: https://git.openjdk.org/jfx/pull/1085 From tsayao at openjdk.org Sat Apr 8 01:03:53 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sat, 8 Apr 2023 01:03:53 GMT Subject: RFR: 8305768: Unify WindowContext in glass-gtk [v2] In-Reply-To: References: Message-ID: > This unifies and organizes WindowContext of the glass-gtk. > > It does not change any behaviour, just reorganizes the code. Thiago Milczarek Sayao has updated the pull request incrementally with one additional commit since the last revision: Unrelated file ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1085/files - new: https://git.openjdk.org/jfx/pull/1085/files/b846ed21..102592e6 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1085&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1085&range=00-01 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1085.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1085/head:pull/1085 PR: https://git.openjdk.org/jfx/pull/1085 From kcr at openjdk.org Sat Apr 8 13:44:46 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 8 Apr 2023 13:44:46 GMT Subject: RFR: 8304041: [WebView] Text on the left and right of emoji is not visible In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 20:00:01 GMT, Phil Race wrote: > This fixes a problem with mixing Emoji and regular text in Webview. > The Prism implementation expects that Emoji will not be in the same call to drawString as regular glyphs, > since they need very different handling. > This fix breaks up the runs webview hands to Prism. > The test program in the bug report now renders properly (which it never did before in any release) The intent is to split up the runs passed into `WCGraphicsPrismContext::drawString` into separate drawString calls in the same way that they would be split if they were drawn in a Label or Text node. It now works correctly for text mixed with simple emojis. For emojis with modifiers, it is better than it was, but is still not equivalent to the same string drawn in a Text node or Label in all cases. I ran the test case attached to [JDK-8303494](https://bugs.openjdk.org/browse/JDK-8303494), and the skin tone modifiers are now displayed in WebView (just like they are in a Label), but the male modifiers are not displayed in WebView (whereas they are in a Label). If I modify your patch to force splitting the string on each character (regardless of whether it is a color glyph or not), then it produces expected result, meaning it is then equivalent to drawing the same string in a Label. Current code (without your fix) produces the following output: emoji-orig This PR produces the following output: emoji-fix Drawing that same string in a Label produces the following output, as does a modified version of your patch that forces each character into its own string: emoji-label Maybe you need to check something other than (or in addition to) "isColorGlyph()" to determine where to split the string? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1083#issuecomment-1500894519 From kcr at openjdk.org Sat Apr 8 15:15:53 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 8 Apr 2023 15:15:53 GMT Subject: RFR: 8301312: Create implementation of NSAccessibilityButton protocol In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 20:43:13 GMT, Alexander Zuev wrote: > Add the common base component for all the new implementing native classes Change native peer creation to use the new base component The new code will instantiate new protocol implementation for the given role if it exists or an old one if it does not exist > Added BUTTON role implementing class Initial testing looks good. I'd like to do some additional testing. I like the approach you chose, since it allows for incremental adoption of the new a11y API. I presume that you will file an RFE to cleanup the deprecated GlassAccessible class once new a11y classes are implemented for all components? I have a question about the scope of this RFE. The JBS issue says that it will use NSAccessiblityButton protocol for `BUTTON`, `INCREMENT_BUTTON`, `DECREMENT_BUTTON`, and `SPLIT_MENU_BUTTON`, but it looks like only the first is implemented. Will that be handled later? If so, then the Description in JBS should be updated. I also left a few inline comments. Nothing major. modules/javafx.graphics/src/main/java/com/sun/glass/ui/mac/MacAccessible.java line 658: > 656: > 657: MacAccessible() { > 658: this.peer = _createGlassAccessible(); Now that you defer the creation of the `peer`, it might be safer to change line 798 to call `getNativeAccessible()` instead of accessing `peer` directly, in case `sendNotification()` is called before `getNativeAccessible()`, unless you know that this can't happen. modules/javafx.graphics/src/main/java/com/sun/glass/ui/mac/MacAccessible.java line 807: > 805: if (this.peer == 0L) { > 806: AccessibleRole role = (AccessibleRole) getAttribute(ROLE); > 807: if (role == null) role = AccessibleRole.NODE; When would `role` be null? And if it is, is defaulting to `NODE` going to do the right thing once you implement the new a11y protocol for Node? modules/javafx.graphics/src/main/java/com/sun/glass/ui/mac/MacAccessible.java line 976: > 974: return -1; > 975: } > 976: This method is not used anywhere (even from native code). modules/javafx.graphics/src/main/native-glass/mac/a11y/AccessibleBase.h line 42: > 40: @end > 41: > 42: jmethodID jAccessibilityAttributeNames; Very minor: missing newline at end of file modules/javafx.graphics/src/main/native-glass/mac/a11y/AccessibleBase.m line 120: > 118: (*env)->CallVoidMethod(env, self->jAccessible, jAccessibilityPerformAction, actionId); > 119: GLASS_CHECK_EXCEPTION(env); > 120: return TRUE; Are there any cases where an exception is possible? If so, then might checking the exception and returning false if there is one be warranted? modules/javafx.graphics/src/main/native-glass/mac/a11y/AccessibleBase.m line 156: > 154: NSString *roleName = jStringToNSString(env, forRole); > 155: Class classType = [AccessibleBase getComponentAccessibilityClass:roleName]; > 156: GlassAccessible* accessible = NULL; It might be clearer to use `NSObject` here (which is the common supertype of `GlassAccessible` and `AccessibileBase`). modules/javafx.graphics/src/main/native-glass/mac/a11y/ButtonAccessibility.h line 37: > 35: - (NSRect)accessibilityFrame; > 36: @end > 37: Very minor: extra newline at the end of file. ------------- PR Review: https://git.openjdk.org/jfx/pull/1084#pullrequestreview-1376768631 PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1161117725 PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1161117486 PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1161117615 PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1161117799 PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1161118971 PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1161119661 PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1161121358 From mstrauss at openjdk.org Sat Apr 8 17:36:49 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 8 Apr 2023 17:36:49 GMT Subject: RFR: JDK-8199216: Memory leak and quadratic layout time with nested nodes (hbox) and pseudo-class in style sheet [v3] In-Reply-To: <71txwbPnADbrDxk1W-0jTe_8O50fqsm0MKi6F1lwVik=.d5851046-2cab-4c21-ab37-7958dfdcd6b5@github.com> References: <71txwbPnADbrDxk1W-0jTe_8O50fqsm0MKi6F1lwVik=.d5851046-2cab-4c21-ab37-7958dfdcd6b5@github.com> Message-ID: On Tue, 4 Apr 2023 09:35:48 GMT, John Hendrikx wrote: >> About allocation free: if the `Set` you pass in is immutable, and it is has a cached equivalent (or it is the same one), then no allocations occur (calculating the hash code does not do allocations, unless someone overrides hash code to do so) -- `copyOf` will not allocate anything if the `Set` was immutable already. >> >> Allocations only occur in two cases: >> - When the set you pass in is not immutable, and it is a new set that wasn't cached yet. A copy is made (allocation) and a `Map.Entry` is created (allocation) >> - When the set you pass in is immutable, but wasn't cached yet. No copy is needed, but still a `Map.Entry` is created. >> >> These allocations however will be only during application startup (when new combinations of pseudo classes are encountered) and the first time some state occurs in your application that results in a new pseudo class combination. The amount of allocations over the life time of your application (from this code) is probably around 50-100. > > Perhaps write some code to show what you mean here? > I could cache the hash code for the sets that are returned here (they are immutable sets returned by `Set.copyOf` -- I checked their code, and they don't cache the hash codes). That would however only help if you often pass in a set that is already cached, to find out if you got the same one. Perhaps this happens a lot, I could test that. That's what I meant to say. It seems like an easy win to cache the hash code of immutable sets if those same immutable sets can concievably be passed into this method quite often. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1076#discussion_r1161138111 From mstrauss at openjdk.org Sat Apr 8 17:39:49 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 8 Apr 2023 17:39:49 GMT Subject: RFR: JDK-8199216: Memory leak and quadratic layout time with nested nodes (hbox) and pseudo-class in style sheet [v3] In-Reply-To: References: <71txwbPnADbrDxk1W-0jTe_8O50fqsm0MKi6F1lwVik=.d5851046-2cab-4c21-ab37-7958dfdcd6b5@github.com> Message-ID: On Sat, 8 Apr 2023 17:33:46 GMT, Michael Strau? wrote: >> Perhaps write some code to show what you mean here? > >> I could cache the hash code for the sets that are returned here (they are immutable sets returned by `Set.copyOf` -- I checked their code, and they don't cache the hash codes). That would however only help if you often pass in a set that is already cached, to find out if you got the same one. Perhaps this happens a lot, I could test that. > > That's what I meant to say. It seems like an easy win to cache the hash code of immutable sets if those same immutable sets can concievably be passed into this method quite often. > Allocations only occur in two cases: > > * When the set you pass in is not immutable, and it is a new set that wasn't cached yet. A copy is made (allocation) and a `Map.Entry` is created (allocation) > * When the set you pass in is immutable, but wasn't cached yet. No copy is needed, but still a `Map.Entry` is created. This method will allocate on every single call because it captures the method argument in a lambda object (but it doesn't need to, it can be written in a way that doesn't use capturing lambdas). That's another easy win to be had if this method is called often. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1076#discussion_r1161138414 From duke at openjdk.org Sat Apr 8 19:14:50 2023 From: duke at openjdk.org (Martin Fox) Date: Sat, 8 Apr 2023 19:14:50 GMT Subject: RFR: 8278924: [Linux] Robot key test can fail if multiple keyboard layouts are installed In-Reply-To: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> References: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> Message-ID: On Mon, 17 Jan 2022 20:25:08 GMT, Martin Fox wrote: > The Robot implementation on Linux did not consult the current layout when mapping from a KeyCode to a hardware code. Internally it retrieved results for all the layouts but just picked the first one it saw leading to random effects. Though not part of the original bug report, the code also ignored the shift level when choosing which result to pick. On a French layout the dollar sign is on two keys (AltGr 4 is the second one) and the code could choose either one. Same is true for pound. > > This PR consults the current layout and only on shift level 0 which is the same level used in get_glass_key to figure out which KeyCode to assign when generating a KeyEvent. For anyone else looking at this code: the GTK documentation on how groups and levels work doesn't match the behavior seen on X11 systems. This whole area is sketchily documented. A quick summary: The keymap includes information on all of the keyboard layouts the user has installed. A call like `gdk_keymap_get_entries_for_keyval` returns results that span all the installed layouts and it's up to the client to sift through them to find the entries relevant to the current layout. The layout is specified in the `group` field which is an index into the user's list of configured layouts with 0 at the top (as presented in the UI). The `level` field indicates the modifier state (0 for unshifted, 1 for shifted, etc.) Under certain circumstances all of the results may be in group 0 even if that's not the active layout. I've seen this happen when the current layout is non-Latin (e.g. Russian) or when querying values on the numeric keypad. So if all the results are in group 0 the group fields should be ignored. If the user configures a non-Latin layout GTK (or XKB) will append an additional U.S. QWERTY layout/group under the hood. Presumably this is added to ensure there's always a Latin layout around to resolve accelerators like Ctrl+C. ------------- PR Comment: https://git.openjdk.org/jfx/pull/718#issuecomment-1500958794 From jhendrikx at openjdk.org Sat Apr 8 19:47:48 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 8 Apr 2023 19:47:48 GMT Subject: RFR: JDK-8304959: Public API in javafx.css.Match should not return private API class PseudoClassState In-Reply-To: References: <-zNr6tpAvHM6uPLbSIoSdws0ASyWrg6U_LJf4R5FTTY=.5f540c9b-4f7c-47ed-9321-61b2c804181d@github.com> Message-ID: On Fri, 7 Apr 2023 21:44:12 GMT, Kevin Rushforth wrote: >> I'll take a closer look early next week. > >> I think that Match is supposed to be immutable, given the non-public constructor. Match itself will never change the set (and nothing else will) so making it observable seems unnecessary. > > Agreed. > >> In other words, simpleSelector.createMatch().getPseudoClasses().clear() would break the Selectors encapsulation. >> >> I think it's best to close that loophole. If you agree, I can document this method that it returns an immutable set, which is also what I assumed would be the case in my other PR where I made many of these immutable. > > Yes, this seems like the best solution to me. > >> Essentially this means that SimpleSelector and CompoundSelector should probably be package private. > > I agree that these two classes should not have been made public when the javafx.css package was created as public API back in JDK 9. > > The usual process for removing API is to deprecate it for removal in one release and then remove it in a future release, but in this case, since those classes cannot be constructed, and are never returned by any public API, any use of them would be relying on an implementation detail (via an `instanceof` and a cast, to no good purpose). > > Since there is no useful way an application could be using these classes, I recommend option 1, as long as those two classes can be cleanly moved to com.sun.javafx.css. Otherwise, we could go with option 2 along with deprecating those two classes for removal. > > The Specification section of the CSR would simply propose to remove those two classes. You could describe what is happening (moving them to a non-exported package) in the Solution section. @kevinrushforth It looks like it will have to be option 2; the reason is that both `Selector` and `Match` are abstract classes (with a package private constructor). The `CompoundSelector` and `SimpleSelector` extend this abstract class (as there is some small overlap). If `Selector` and `Match` had been interfaces, it would have allowed this. I couldn't find anything about binary compatibility when changing an abstract class with a package private constructor to an interface, so I tested it and I got an `IncompatibleClassChangeError` when calling `Selector Selector.createSelector(...)` method. Apparently, the compiled method call does encode the difference between an interface and a class: invokestatic #7 // Method Selector.createSelector:(I)LSelector; vs: invokestatic #7 // InterfaceMethod Selector.createSelector:(I)LSelector; At the most, I could make `CompoundSelector` and `SimpleSelector` package private, or nested classes in `Selector`; they would at least be hidden then. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1070#discussion_r1161150369 From jhendrikx at openjdk.org Sat Apr 8 20:33:43 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 8 Apr 2023 20:33:43 GMT Subject: RFR: JDK-8304959: Public API in javafx.css.Match should not return private API class PseudoClassState [v2] In-Reply-To: References: Message-ID: <828xL7dlcVhpAE6y2oiM61OYVlZXp2DmWcZrJyvggkw=.f687598e-c2fc-4d2a-bb03-3132a4d100cb@github.com> > The class `PseudoClassState` is private API, but was exposed erroneously in the CSS API. Instead, `Set` should have been used. This PR corrects this. John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Ensure Set PseudoClass and StyleClass are immutable in CSS API Updated documentation, fixed warnings and removed some unnecessary code ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1070/files - new: https://git.openjdk.org/jfx/pull/1070/files/dffc6f47..9bbe9259 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1070&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1070&range=00-01 Stats: 62 lines in 4 files changed: 16 ins; 13 del; 33 mod Patch: https://git.openjdk.org/jfx/pull/1070.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1070/head:pull/1070 PR: https://git.openjdk.org/jfx/pull/1070 From jhendrikx at openjdk.org Sat Apr 8 21:30:40 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 8 Apr 2023 21:30:40 GMT Subject: RFR: JDK-8304959: Public API in javafx.css.Match should not return private API class PseudoClassState [v3] In-Reply-To: References: Message-ID: > The class `PseudoClassState` is private API, but was exposed erroneously in the CSS API. Instead, `Set` should have been used. This PR corrects this. John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: - Remove unused methods - Fix build by pulling in partial fix for BitSet class ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1070/files - new: https://git.openjdk.org/jfx/pull/1070/files/9bbe9259..73fa672e Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1070&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1070&range=01-02 Stats: 111 lines in 2 files changed: 33 ins; 59 del; 19 mod Patch: https://git.openjdk.org/jfx/pull/1070.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1070/head:pull/1070 PR: https://git.openjdk.org/jfx/pull/1070 From jhendrikx at openjdk.org Sat Apr 8 21:30:43 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 8 Apr 2023 21:30:43 GMT Subject: RFR: JDK-8304959: Public API in javafx.css.Match should not return private API class PseudoClassState [v2] In-Reply-To: <828xL7dlcVhpAE6y2oiM61OYVlZXp2DmWcZrJyvggkw=.f687598e-c2fc-4d2a-bb03-3132a4d100cb@github.com> References: <828xL7dlcVhpAE6y2oiM61OYVlZXp2DmWcZrJyvggkw=.f687598e-c2fc-4d2a-bb03-3132a4d100cb@github.com> Message-ID: On Sat, 8 Apr 2023 20:33:43 GMT, John Hendrikx wrote: >> The class `PseudoClassState` is private API, but was exposed erroneously in the CSS API. Instead, `Set` should have been used. This PR corrects this. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Ensure Set PseudoClass and StyleClass are immutable in CSS API > > Updated documentation, fixed warnings and removed some unnecessary code I think this is the best that can be done for now. There are still some mutable aspects to `Selector` (you can change the `Rule` and the ordinal of one). I'm really not quite sure why it is done that way, it seems there was may have been some vision that these classes could be used to "edit" a stylesheet -- something that's probably best done with a different set of classes to avoid burdening regular read-only CSS work with editable variants, requiring defensive copying everywhere. Ideally, `Selector` and `Match` would have been interfaces, and the private code should work with the CSS classes only through those. Changing them to interfaces now seems impossible, it's not binary compatible, and I don't see a deprecation route to get there. However, it is still possible to improve the situation a bit (in another PR perhaps), as the private code only requires a few additional methods to be made public API on `Selector` to remove its direct dependencies on `SimpleSelector` and `CompoundSelector`: - getName() which returns the java class name to which the selector is applied - getId() returns the CSS id (if any) of a Selector - getStyleClassSet() returns the (immutable) style classes of a Selector These three methods are implemented by `SimpleSelector`, but not by `CompoundSelector`. Instead, its last selector is extracted (which is always a `SimpleSelector`) and the methods are called on those. These methods could be made part of `Selector`, then `CompoundSelector` implements them by directing them to its last `SimpleSelector`, and the private code would not need to care about the selector type anymore. These selector classes could then be hidden completely. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1070#issuecomment-1500980591 From jhendrikx at openjdk.org Sat Apr 8 21:31:01 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 8 Apr 2023 21:31:01 GMT Subject: RFR: JDK-8304959: Public API in javafx.css.Match should not return private API class PseudoClassState [v2] In-Reply-To: <828xL7dlcVhpAE6y2oiM61OYVlZXp2DmWcZrJyvggkw=.f687598e-c2fc-4d2a-bb03-3132a4d100cb@github.com> References: <828xL7dlcVhpAE6y2oiM61OYVlZXp2DmWcZrJyvggkw=.f687598e-c2fc-4d2a-bb03-3132a4d100cb@github.com> Message-ID: On Sat, 8 Apr 2023 20:33:43 GMT, John Hendrikx wrote: >> The class `PseudoClassState` is private API, but was exposed erroneously in the CSS API. Instead, `Set` should have been used. This PR corrects this. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Ensure Set PseudoClass and StyleClass are immutable in CSS API > > Updated documentation, fixed warnings and removed some unnecessary code I had to pull in some of the fixes I did in `BitSet` in https://github.com/openjdk/jfx/pull/1076 Just wrapping a `Set` in an unmodifiable set is enough to break lots of tests, because `BitSet` has many methods that will simply do nothing if the "other" `Set` is not a `BitSet`. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1070#issuecomment-1500980807 From jhendrikx at openjdk.org Sat Apr 8 21:39:48 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 8 Apr 2023 21:39:48 GMT Subject: RFR: JDK-8304959: Public API in javafx.css.Match should not return private API class PseudoClassState In-Reply-To: References: Message-ID: On Thu, 30 Mar 2023 22:25:29 GMT, Kevin Rushforth wrote: >> This was clearly a mistake back when the public API was first created in JDK 9. > >> @kevinrushforth I've created the CSR for this. Can I move it to proposed? > > I took a quick look, and it is fine to move to Proposed. @kevinrushforth about the CSR -- as I couldn't move the classes to non-public hierarchy, I think the CSR is currently correct. I also removed a public method in `SimpleSelector` as it wasn't used (and as discussed before, nobody can reach it without casting). There were a few javadoc only changes that could be seen as clarification (whether something can be `null` or whether it is immutable). I could include those in the CSR. If we want to move forward later to perhaps try and remove `SimpleSelector` and `CompoundSelector` (perhaps by adding those few public API methods to `Selector`), I could already mark these deprecated (or I could do so to indicate they shouldn't be used at all, whether we want to remove them or not). What do you think? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1070#issuecomment-1500982072 From jhendrikx at openjdk.org Sat Apr 8 21:44:41 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 8 Apr 2023 21:44:41 GMT Subject: RFR: JDK-8304959: Public API in javafx.css.Match should not return private API class PseudoClassState [v4] In-Reply-To: References: Message-ID: <7e-ryyUZy0JlDiayN1MDWR_O967B01vusbGgmQjzUPo=.83534825-1333-48fa-827d-60145f46fe3e@github.com> > The class `PseudoClassState` is private API, but was exposed erroneously in the CSS API. Instead, `Set` should have been used. This PR corrects this. John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Fix tests, don't call addAll with null ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1070/files - new: https://git.openjdk.org/jfx/pull/1070/files/73fa672e..144e04cf Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1070&range=03 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1070&range=02-03 Stats: 8 lines in 1 file changed: 6 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jfx/pull/1070.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1070/head:pull/1070 PR: https://git.openjdk.org/jfx/pull/1070 From nlisker at openjdk.org Sat Apr 8 23:58:48 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Sat, 8 Apr 2023 23:58:48 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: References: Message-ID: On Fri, 7 Apr 2023 06:36:50 GMT, John Hendrikx wrote: >> Description copied from issue: >> >> There are up to two additional invalidations performed that really should be avoided, causing downstream fluent bindings to be recomputed with the same values. This is very confusing as these should only be called when there is an actual change, and not called for the same value multiple times in a row. >> >> These two extra invalidations have two different causes, each causing an additional invalidation to be triggered: >> >> 1) ObjectBinding's `isObserved` is delayed slightly. When you add a listener, the listener is added internally and the binding is made valid; this triggers some downstream activity which checks the `isObserved` status to decide whether to start observation of properties -- unfortunately this still returns `false` at that time. A work-around for this existed by calling `getValue` again in `LazyObjectBinding` with a huge comment explaining why this is needed. Although this works, it still means that a downstream function like `map` is called an additional time while it should really only be called once. >> >> The solution is to ensure `isObserved` returns `true` before the `ExpressionHelper` is called. Already verified this solves the problem. This also means the work-around in `LazyObjectBinding` is no longer needed, which seems like a big win. >> >> 2) The second additional call originates from a different issue. When `ConditionalBinding` (which implements the `when` construct) sees its condition property changing, it always invalidates itself. This is however only necessary if the current cached value (if it was valid) differs from the current source value. To prevent an unnecessary invalidation, and the resulting revalidation calls that this will trigger, a simple check to see if the value actually changed before invalidating solves this problem. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Fix review comments I reviewed the first bug and the fix looks good. The fix adds a `boolean` field to all `ObjectBinding`s, which could be a slight performance hit. I have a local version of a refactored `ExpressionHelper` class that uses a singleton instance for an empty helper instead of `null`. It makes the code cleaner (no special `null` handling) and will allow to get rid of the new `observed` field because that info can be encoded in `ExpressionHelper` instead of in `ObjectBinding`. After all, the info of being observed really belongs in the class that manages the listeners IMO. Not sure if it's worth pursuing at the moment. Also, I really wish we could make `add/removeListener` throw on `null` :) I still need to finish reviewing the second bug. The logic flow is a bit complicated when taking into account the many states the binding can be at (valid, observed, active...). One question I have is about the tests: why split a When test class from an already existing one in the fluent bindings test? ------------- PR Review: https://git.openjdk.org/jfx/pull/1056#pullrequestreview-1376817231 From jhendrikx at openjdk.org Sun Apr 9 08:52:42 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 9 Apr 2023 08:52:42 GMT Subject: RFR: JDK-8304959: Public API in javafx.css.Match should not return private API class PseudoClassState [v5] In-Reply-To: References: Message-ID: > The class `PseudoClassState` is private API, but was exposed erroneously in the CSS API. Instead, `Set` should have been used. This PR corrects this. John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Add missing null check ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1070/files - new: https://git.openjdk.org/jfx/pull/1070/files/144e04cf..d2651894 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1070&range=04 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1070&range=03-04 Stats: 5 lines in 2 files changed: 2 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jfx/pull/1070.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1070/head:pull/1070 PR: https://git.openjdk.org/jfx/pull/1070 From jhendrikx at openjdk.org Sun Apr 9 09:06:52 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 9 Apr 2023 09:06:52 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: References: Message-ID: On Sat, 8 Apr 2023 23:56:10 GMT, Nir Lisker wrote: > I reviewed the first bug and the fix looks good. > > The fix adds a `boolean` field to all `ObjectBinding`s, which could be a slight performance hit. I have a local version of a refactored `ExpressionHelper` class that uses a singleton instance for an empty helper instead of `null`. It makes the code cleaner (no special `null` handling) and will allow to get rid of the new `observed` field because that info can be encoded in `ExpressionHelper` instead of in `ObjectBinding`. After all, the info of being observed really belongs in the class that manages the listeners IMO. Not sure if it's worth pursuing at the moment. I think something will need to change with the `ExpressionHelper` given the amount of problems it has currently. At that time the boolean could be removed again. > Also, I really wish we could make `add/removeListener` throw on `null` :) You mean immediately? Because the `null` check is done by `ExpressionHelper` already. What I wish for is that `removeListener` would throw when removing non-existing listeners; that would expose a ton of logic errors where code is removing some listener that it thought was present, but wasn't... > I still need to finish reviewing the second bug. The logic flow is a bit complicated when taking into account the many states the binding can be at (valid, observed, active...). One question I have is about the tests: why split a When test class from an already existing one in the fluent bindings test? I mainly did that as I felt it didn't fit well in the structure of that other test, but it could be added there. I also think that big test class may benefit from splitting up; it was getting a bit unwieldy. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1056#issuecomment-1501081120 From jhendrikx at openjdk.org Sun Apr 9 09:22:54 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 9 Apr 2023 09:22:54 GMT Subject: RFR: JDK-8304959: Public API in javafx.css.Match should not return private API class PseudoClassState [v6] In-Reply-To: References: Message-ID: <_PrViuFXWq5IapY4T5Z8TsvG9qJkzf_rm4XRxxk_NsQ=.a4d31346-8d99-4263-be26-e0cfb824588a@github.com> > The class `PseudoClassState` is private API, but was exposed erroneously in the CSS API. Instead, `Set` should have been used. This PR corrects this. John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Fix PseudoClassTest ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1070/files - new: https://git.openjdk.org/jfx/pull/1070/files/d2651894..bcc9a941 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1070&range=05 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1070&range=04-05 Stats: 22 lines in 1 file changed: 2 ins; 18 del; 2 mod Patch: https://git.openjdk.org/jfx/pull/1070.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1070/head:pull/1070 PR: https://git.openjdk.org/jfx/pull/1070 From nlisker at openjdk.org Sun Apr 9 17:06:42 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Sun, 9 Apr 2023 17:06:42 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: References: Message-ID: <5Zdj8kS4aHACbmyZAzau3bP26D04Su1TnJqNerz7BjI=.c2678ba2-1af6-470c-a283-ee9511a8910e@github.com> On Fri, 7 Apr 2023 06:36:50 GMT, John Hendrikx wrote: >> Description copied from issue: >> >> There are up to two additional invalidations performed that really should be avoided, causing downstream fluent bindings to be recomputed with the same values. This is very confusing as these should only be called when there is an actual change, and not called for the same value multiple times in a row. >> >> These two extra invalidations have two different causes, each causing an additional invalidation to be triggered: >> >> 1) ObjectBinding's `isObserved` is delayed slightly. When you add a listener, the listener is added internally and the binding is made valid; this triggers some downstream activity which checks the `isObserved` status to decide whether to start observation of properties -- unfortunately this still returns `false` at that time. A work-around for this existed by calling `getValue` again in `LazyObjectBinding` with a huge comment explaining why this is needed. Although this works, it still means that a downstream function like `map` is called an additional time while it should really only be called once. >> >> The solution is to ensure `isObserved` returns `true` before the `ExpressionHelper` is called. Already verified this solves the problem. This also means the work-around in `LazyObjectBinding` is no longer needed, which seems like a big win. >> >> 2) The second additional call originates from a different issue. When `ConditionalBinding` (which implements the `when` construct) sees its condition property changing, it always invalidates itself. This is however only necessary if the current cached value (if it was valid) differs from the current source value. To prevent an unnecessary invalidation, and the resulting revalidation calls that this will trigger, a simple check to see if the value actually changed before invalidating solves this problem. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Fix review comments About the second bug. I tested that there are no extra invalidation events after the patch that were occurring without it. Isn't this something there should be a test for (a counter for invalidation events)? modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 51: > 49: > 50: @Test > 51: void shouldNeverCallDownstreamMapFunction() { I would add a comment that says why it should never call it. Since this applies to the `StartsTrue` method too, you can put that comment on their class. modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 81: > 79: condition.set(true); > 80: > 81: assertEquals(List.of(), observedMappings); Is this part necessary? The method that starts with `true` already checks the transition to `false`. That is, after line 63 `condition.set(true);`, aren't we at the exact same state that the other method starts at? Same comment for the observed variant. modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 127: > 125: @Nested > 126: class WhenObserved { > 127: @Nested New line for consistency. modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 139: > 137: property.when(condition) > 138: .map(x -> { observedMappings.add(x); return x; }) > 139: .addListener((obs, old, current) -> observedChanges.add(old + " -> " + current)); What do you think about a variant with an invalidation listener? ------------- PR Review: https://git.openjdk.org/jfx/pull/1056#pullrequestreview-1376933269 PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1161311512 PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1161312432 PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1161311571 PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1161311846 From nlisker at openjdk.org Sun Apr 9 17:34:44 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Sun, 9 Apr 2023 17:34:44 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: References: Message-ID: On Sun, 9 Apr 2023 09:04:15 GMT, John Hendrikx wrote: > > Also, I really wish we could make `add/removeListener` throw on `null` :) > > You mean immediately? Because the `null` check is done by `ExpressionHelper` already. What I wish for is that `removeListener` would throw when removing non-existing listeners; that would expose a ton of logic errors where code is removing some listener that it thought was present, but wasn't... I thought about throwing immediately, but you're right, it throws early enough. Not sure if the NPE should be documented on those methods or if it's obvious. And yes, throwing on non-existing listeners removal could make sense. I'm curious what breaks in JavaFX if this change is done. Could reveal some bugs maybe. > > I still need to finish reviewing the second bug. The logic flow is a bit complicated when taking into account the many states the binding can be at (valid, observed, active...). One question I have is about the tests: why split a When test class from an already existing one in the fluent bindings test? > > I mainly did that as I felt it didn't fit well in the structure of that other test, but it could be added there. I also think that big test class may benefit from splitting up; it was getting a bit unwieldy. Yeah, `ObservableValueFluentBindingsTest` is very long. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1056#issuecomment-1501171072 From jhendrikx at openjdk.org Sun Apr 9 20:51:15 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 9 Apr 2023 20:51:15 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: <5Zdj8kS4aHACbmyZAzau3bP26D04Su1TnJqNerz7BjI=.c2678ba2-1af6-470c-a283-ee9511a8910e@github.com> References: <5Zdj8kS4aHACbmyZAzau3bP26D04Su1TnJqNerz7BjI=.c2678ba2-1af6-470c-a283-ee9511a8910e@github.com> Message-ID: On Sun, 9 Apr 2023 16:42:10 GMT, Nir Lisker wrote: >> John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix review comments > > modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 139: > >> 137: property.when(condition) >> 138: .map(x -> { observedMappings.add(x); return x; }) >> 139: .addListener((obs, old, current) -> observedChanges.add(old + " -> " + current)); > > What do you think about a variant with an invalidation listener? That's not really useful as there is no way to make such a fluent binding valid again (it would invalidate once, and never become valid). The only way to make it valid would be to assign the result of `map` to a variable, and call `get` on that. I can however add a test that proves the above :) ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1161339438 From jhendrikx at openjdk.org Sun Apr 9 20:56:02 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 9 Apr 2023 20:56:02 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: References: <5Zdj8kS4aHACbmyZAzau3bP26D04Su1TnJqNerz7BjI=.c2678ba2-1af6-470c-a283-ee9511a8910e@github.com> Message-ID: On Sun, 9 Apr 2023 20:48:50 GMT, John Hendrikx wrote: >> modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 139: >> >>> 137: property.when(condition) >>> 138: .map(x -> { observedMappings.add(x); return x; }) >>> 139: .addListener((obs, old, current) -> observedChanges.add(old + " -> " + current)); >> >> What do you think about a variant with an invalidation listener? > > That's not really useful as there is no way to make such a fluent binding valid again (it would invalidate once, and never become valid). The only way to make it valid would be to assign the result of `map` to a variable, and call `get` on that. > > I can however add a test that proves the above :) Also, the test is specifically looking how often `map` is called here (which is triggered by invalidations from the `when`). The listener is only there to make sure that `map` has installed its listeners as fluent observables don't install them when not observed themselves. I could have used an `InvalidationListener` here for this purpose, but then I'd still need to call `getValue` on the `map` observable as otherwise it will definitely not map anything as it is invalid. Perhaps a simple test that shows this is the case can be useful. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1161339789 From jhendrikx at openjdk.org Sun Apr 9 21:15:29 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 9 Apr 2023 21:15:29 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: <5Zdj8kS4aHACbmyZAzau3bP26D04Su1TnJqNerz7BjI=.c2678ba2-1af6-470c-a283-ee9511a8910e@github.com> References: <5Zdj8kS4aHACbmyZAzau3bP26D04Su1TnJqNerz7BjI=.c2678ba2-1af6-470c-a283-ee9511a8910e@github.com> Message-ID: On Sun, 9 Apr 2023 16:46:44 GMT, Nir Lisker wrote: >> John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix review comments > > modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 81: > >> 79: condition.set(true); >> 80: >> 81: assertEquals(List.of(), observedMappings); > > Is this part necessary? The method that starts with `true` already checks the transition to `false`. That is, after line 63 `condition.set(true);`, aren't we at the exact same state that the other method starts at? > > Same comment for the observed variant. It's not strictly needed, I just want to eliminate any possibility that a different initial state could affect the results. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1161341624 From jhendrikx at openjdk.org Sun Apr 9 21:27:36 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 9 Apr 2023 21:27:36 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v3] In-Reply-To: References: Message-ID: <-LO-7b7wb0L55OTfiObMEeAAXn3PjPSe5v7bVq2EMsc=.48b6595b-543d-4630-aec6-f6c11b597851@github.com> > Description copied from issue: > > There are up to two additional invalidations performed that really should be avoided, causing downstream fluent bindings to be recomputed with the same values. This is very confusing as these should only be called when there is an actual change, and not called for the same value multiple times in a row. > > These two extra invalidations have two different causes, each causing an additional invalidation to be triggered: > > 1) ObjectBinding's `isObserved` is delayed slightly. When you add a listener, the listener is added internally and the binding is made valid; this triggers some downstream activity which checks the `isObserved` status to decide whether to start observation of properties -- unfortunately this still returns `false` at that time. A work-around for this existed by calling `getValue` again in `LazyObjectBinding` with a huge comment explaining why this is needed. Although this works, it still means that a downstream function like `map` is called an additional time while it should really only be called once. > > The solution is to ensure `isObserved` returns `true` before the `ExpressionHelper` is called. Already verified this solves the problem. This also means the work-around in `LazyObjectBinding` is no longer needed, which seems like a big win. > > 2) The second additional call originates from a different issue. When `ConditionalBinding` (which implements the `when` construct) sees its condition property changing, it always invalidates itself. This is however only necessary if the current cached value (if it was valid) differs from the current source value. To prevent an unnecessary invalidation, and the resulting revalidation calls that this will trigger, a simple check to see if the value actually changed before invalidating solves this problem. John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Address review comments - Added extra tests cases that count invalidations - Added explanatory comment ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1056/files - new: https://git.openjdk.org/jfx/pull/1056/files/33bb5691..472cefb2 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1056&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1056&range=01-02 Stats: 132 lines in 1 file changed: 132 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jfx/pull/1056.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1056/head:pull/1056 PR: https://git.openjdk.org/jfx/pull/1056 From jhendrikx at openjdk.org Sun Apr 9 21:27:37 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 9 Apr 2023 21:27:37 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: References: <5Zdj8kS4aHACbmyZAzau3bP26D04Su1TnJqNerz7BjI=.c2678ba2-1af6-470c-a283-ee9511a8910e@github.com> Message-ID: On Sun, 9 Apr 2023 20:53:48 GMT, John Hendrikx wrote: >> That's not really useful as there is no way to make such a fluent binding valid again (it would invalidate once, and never become valid). The only way to make it valid would be to assign the result of `map` to a variable, and call `get` on that. >> >> I can however add a test that proves the above :) > > Also, the test is specifically looking how often `map` is called here (which is triggered by invalidations from the `when`). The listener is only there to make sure that `map` has installed its listeners as fluent observables don't install them when not observed themselves. I could have used an `InvalidationListener` here for this purpose, but then I'd still need to call `getValue` on the `map` observable as otherwise it will definitely not map anything as it is invalid. > > Perhaps a simple test that shows this is the case can be useful. I've added a variant with an InvalidationListener directly on the when binding. It works as I would expect, it's maybe a more useful test than the others (it basically tests the same thing, but more directly). ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1161342589 From jhendrikx at openjdk.org Sun Apr 9 21:28:47 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 9 Apr 2023 21:28:47 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v2] In-Reply-To: <5Zdj8kS4aHACbmyZAzau3bP26D04Su1TnJqNerz7BjI=.c2678ba2-1af6-470c-a283-ee9511a8910e@github.com> References: <5Zdj8kS4aHACbmyZAzau3bP26D04Su1TnJqNerz7BjI=.c2678ba2-1af6-470c-a283-ee9511a8910e@github.com> Message-ID: On Sun, 9 Apr 2023 16:55:50 GMT, Nir Lisker wrote: > About the second bug. I tested that there are no extra invalidation events after the patch that were occurring without it. Isn't this something there should be a test for (a counter for invalidation events)? I think I misunderstood this comment, there is definitely a test that fails, but I think you meant why I did not verify the problem with an invalidation listener directly... I guess I just wanted to be sure it worked in combination with downstream bindings (as that's how I discovered the issue). I have added that now though. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1056#issuecomment-1501217429 From nlisker at openjdk.org Sun Apr 9 23:28:50 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Sun, 9 Apr 2023 23:28:50 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v3] In-Reply-To: <-LO-7b7wb0L55OTfiObMEeAAXn3PjPSe5v7bVq2EMsc=.48b6595b-543d-4630-aec6-f6c11b597851@github.com> References: <-LO-7b7wb0L55OTfiObMEeAAXn3PjPSe5v7bVq2EMsc=.48b6595b-543d-4630-aec6-f6c11b597851@github.com> Message-ID: On Sun, 9 Apr 2023 21:27:36 GMT, John Hendrikx wrote: >> Description copied from issue: >> >> There are up to two additional invalidations performed that really should be avoided, causing downstream fluent bindings to be recomputed with the same values. This is very confusing as these should only be called when there is an actual change, and not called for the same value multiple times in a row. >> >> These two extra invalidations have two different causes, each causing an additional invalidation to be triggered: >> >> 1) ObjectBinding's `isObserved` is delayed slightly. When you add a listener, the listener is added internally and the binding is made valid; this triggers some downstream activity which checks the `isObserved` status to decide whether to start observation of properties -- unfortunately this still returns `false` at that time. A work-around for this existed by calling `getValue` again in `LazyObjectBinding` with a huge comment explaining why this is needed. Although this works, it still means that a downstream function like `map` is called an additional time while it should really only be called once. >> >> The solution is to ensure `isObserved` returns `true` before the `ExpressionHelper` is called. Already verified this solves the problem. This also means the work-around in `LazyObjectBinding` is no longer needed, which seems like a big win. >> >> 2) The second additional call originates from a different issue. When `ConditionalBinding` (which implements the `when` construct) sees its condition property changing, it always invalidates itself. This is however only necessary if the current cached value (if it was valid) differs from the current source value. To prevent an unnecessary invalidation, and the resulting revalidation calls that this will trigger, a simple check to see if the value actually changed before invalidating solves this problem. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Address review comments > > - Added extra tests cases that count invalidations > - Added explanatory comment I like the test coverage now. I tried to test the condition else if (isValid() && source.getValue() != getValue()) { invalidate(); } with this sequence: property.set("e"); condition.set(false); property.set("y"); property.set("e"); condition.set(true); I wanted to test the change to the behavior of the condition changing while the binding is valid, and the value is the same. However, the check for the value is done with reference equality, so it will always invalidate (unless I create my own objects and reuse them). Is this to align with the behavior of a change, or will `equals` make more sense here? Also, some of the comments are too long. You can move them above the line you are commenting on and break the lines. modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 144: > 142: > 143: @Test > 144: void shouldCallDownstreamMapFunctionOnlyWhenAbsolutelyNecessary() { Minor: in other functions you used "AbsolutelyNeeded". You can align the names if you want. modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 260: > 258: assertEquals(0, observedInvalidations.get()); > 259: > 260: when.getValue(); // would make no difference, inactive when bindings are always valid Did you mean "always valid when bindings are inactive"? Or maybe that when the binding is valid the listener is inactive? This sentence is confusing to me. ------------- PR Review: https://git.openjdk.org/jfx/pull/1056#pullrequestreview-1376963070 PR Comment: https://git.openjdk.org/jfx/pull/1056#issuecomment-1501236106 PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1161349908 PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1161350295 From jhendrikx at openjdk.org Mon Apr 10 00:16:49 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 10 Apr 2023 00:16:49 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v3] In-Reply-To: <-LO-7b7wb0L55OTfiObMEeAAXn3PjPSe5v7bVq2EMsc=.48b6595b-543d-4630-aec6-f6c11b597851@github.com> References: <-LO-7b7wb0L55OTfiObMEeAAXn3PjPSe5v7bVq2EMsc=.48b6595b-543d-4630-aec6-f6c11b597851@github.com> Message-ID: <_vF5M6ym104Ah0W0tpby9uv-GZsS0nwpVtwoktKSa1M=.96ea4378-0cb5-496a-bd22-ce797468127c@github.com> On Sun, 9 Apr 2023 21:27:36 GMT, John Hendrikx wrote: >> Description copied from issue: >> >> There are up to two additional invalidations performed that really should be avoided, causing downstream fluent bindings to be recomputed with the same values. This is very confusing as these should only be called when there is an actual change, and not called for the same value multiple times in a row. >> >> These two extra invalidations have two different causes, each causing an additional invalidation to be triggered: >> >> 1) ObjectBinding's `isObserved` is delayed slightly. When you add a listener, the listener is added internally and the binding is made valid; this triggers some downstream activity which checks the `isObserved` status to decide whether to start observation of properties -- unfortunately this still returns `false` at that time. A work-around for this existed by calling `getValue` again in `LazyObjectBinding` with a huge comment explaining why this is needed. Although this works, it still means that a downstream function like `map` is called an additional time while it should really only be called once. >> >> The solution is to ensure `isObserved` returns `true` before the `ExpressionHelper` is called. Already verified this solves the problem. This also means the work-around in `LazyObjectBinding` is no longer needed, which seems like a big win. >> >> 2) The second additional call originates from a different issue. When `ConditionalBinding` (which implements the `when` construct) sees its condition property changing, it always invalidates itself. This is however only necessary if the current cached value (if it was valid) differs from the current source value. To prevent an unnecessary invalidation, and the resulting revalidation calls that this will trigger, a simple check to see if the value actually changed before invalidating solves this problem. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Address review comments > > - Added extra tests cases that count invalidations > - Added explanatory comment > I like the test coverage now. > > I tried to test the condition > > ```java > else if (isValid() && source.getValue() != getValue()) { > invalidate(); > } > ``` > > with this sequence: > > ```java > property.set("e"); > condition.set(false); > property.set("y"); > property.set("e"); > condition.set(true); > ``` > > I wanted to test the change to the behavior of the condition changing while the binding is valid, and the value is the same. However, the check for the value is done with reference equality, so it will always invalidate (unless I create my own objects and reuse them). Is this to align with the behavior of a change, or will `equals` make more sense here? Well, I am just following the specification here, but JavaFX itself isn't... We may need to make a decision here. JavaFX is not consistent itself where it applies `equals` and where it uses reference equality: |Class|Equality Type| |---|---| |*PropertyBase except String in setValue|==| |StringPropertyBase in setValue|equals| |ExpressionHelper before calling ChangeListeners|equals| The specification on `ObservableValue` says: > All implementing classes in the JavaFX library check for a change using reference equality (and not object equality, {@code Object#equals(Object)}) of the value. But I'm afraid that's not true. While indeed all the PropertyBase classes "setValue" methods (aside from String), use reference equality, this is not the case for the helper they use for notifying listeners (`ExpressionHelper` uses `equals`). For immutable classes, this is absolutely fine, and this is why it works pretty okay for `StringPropertyBase`. However, using equals on **mutable** classes is going to land you into trouble, as you may miss reference changes that turn out to be significant later (ie. two instances may be equals now, but they may not be equals in the future, and if you have the wrong reference, you will not have the correct instance). There is a test that shows how this can fail with an `ObjectProperty` (although it has nothing to do with the `ObservableList`... `ObjectProperty` would have similar problems): `LambdaMultipleListHandlerTest#testInvalidationOfListValuedObservable`, but it is easy enough to reproduce yourself: SomethingMutable instance1 = ...; SomethingMutable instance2 = instance1.clone(); ObjectProperty prop = new SimpleObjectProperty<>(instance1); prop.addListener((obj, o, n) -> { store n somewhere }); prop.setValue(instance2); // invalidates, but won't inform change listeners as they're equals // the value stored by the change listener is now the WRONG instance!! Also see my post of 21/3/2023 "Changes detected by reference equality for all ObservableValues... except String" on the mailinglist. # Solution Proposal As said before, `equals` and immutable types are not the problem. You get in trouble when types are mutable. So I propose the following: use reference equality everywhere but give String a special status. Why String? It is immutable and has a special status in Java, similar to primitive types (ie, it has its own operator `+`, and can be declared without `new String`). Arrays also are special in Java, but these are mutable so reference equality is what we'd want here. I further propose to put this new form of JavaFX equality in a common class, so it can be used easily whenever you need to do check equality (like in a binding or `ExpressionHelper` for example). Testing by reference equality is really the best solution... you may get a change you didn't want, but at least you are kept up to date with the correct instance. For Strings we can make an exception, but using `equals` for all other object types, which includes mutable types, is going to cause headaches. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1056#issuecomment-1501249711 From kpk at openjdk.org Mon Apr 10 08:32:33 2023 From: kpk at openjdk.org (Karthik P K) Date: Mon, 10 Apr 2023 08:32:33 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu [v2] In-Reply-To: References: Message-ID: > When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. > > Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. > > Added system test to validate the fix. Karthik P K has updated the pull request incrementally with one additional commit since the last revision: Renamed package to match coding convention ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1082/files - new: https://git.openjdk.org/jfx/pull/1082/files/5b496790..1e91b094 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1082&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1082&range=00-01 Stats: 2 lines in 2 files changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jfx/pull/1082.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1082/head:pull/1082 PR: https://git.openjdk.org/jfx/pull/1082 From fkirmaier at openjdk.org Mon Apr 10 12:51:56 2023 From: fkirmaier at openjdk.org (Florian Kirmaier) Date: Mon, 10 Apr 2023 12:51:56 GMT Subject: Integrated: 8303740 JavaFX - Leak in Logging, Logging remembers last exception In-Reply-To: References: Message-ID: On Tue, 7 Mar 2023 11:59:20 GMT, Florian Kirmaier wrote: > When an exception is logged in JavaFX, then the exception is kept in a reference. > This way, always the last logged exception is retained. > > This is a memory-leak. > This was done to write unit-tests to ensure certain error-cases are logged. > > A simple fix is, to add a flag, to enable/disable retaining the exception. This pull request has now been integrated. Changeset: 18e40216 Author: Florian Kirmaier Committer: Kevin Rushforth URL: https://git.openjdk.org/jfx/commit/18e4021651c9e0db21f6817ed2c01ba4ca73781c Stats: 74 lines in 3 files changed: 73 ins; 0 del; 1 mod 8303740: JavaFX - Leak in Logging, Logging remembers last exception Reviewed-by: kcr ------------- PR: https://git.openjdk.org/jfx/pull/1053 From kevin.rushforth at oracle.com Mon Apr 10 16:44:24 2023 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Mon, 10 Apr 2023 09:44:24 -0700 Subject: Proposed schedule for JavaFX 21 Message-ID: <854a5a1a-b9a9-cbcb-9866-7d715b199de6@oracle.com> Here is the proposed schedule for JavaFX 21. RDP1: Jul 13, 2023 (aka ?feature freeze?) RDP2: Aug 3, 2023 Freeze: Aug 31, 2023 GA: Sep 19, 2023 We plan to fork a jfx21 stabilization branch at RDP1. The start of RDP1, the start of RDP2, and the code freeze will be 16:00 UTC on the respective dates. Please let Johan or me know if you have any questions. -- Kevin From tsayao at openjdk.org Mon Apr 10 17:36:53 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Mon, 10 Apr 2023 17:36:53 GMT Subject: Integrated: 8260528: Clean glass-gtk sizing and positioning code In-Reply-To: <5-LHfl6_vdrmRjLivevBopnWBbzgO0ygK1dRPAFdzoM=.22e09b72-4142-4c1c-b320-94a1c48aaa69@github.com> References: <5-LHfl6_vdrmRjLivevBopnWBbzgO0ygK1dRPAFdzoM=.22e09b72-4142-4c1c-b320-94a1c48aaa69@github.com> Message-ID: On Thu, 13 Oct 2022 00:48:09 GMT, Thiago Milczarek Sayao wrote: > This cleans size and positioning code, reducing special cases, code complexity and size. > > Changes: > > - cached extents: 28, 1, 1, 1 are old defaults - modern gnome uses different sizes. It does not assume any size because it varies - it does cache because it's unlikely to vary on the same system - but if it does occur, it will only waste a resize event. > - window geometry, min/max size are centralized in `update_window_constraints`; > - Frame extents (the window decoration size used for "total window size"): > - frame extents are received in `process_property_notify`; > - removed quirks in java code; > - When received, call `set_bounds` again to adjust the size (to account decorations later received); > - Removed `activate_window` because it's the same as focusing the window. `gtk_window_present` will deiconify and focus it. > - `ensure_window_size` was a quirk - removed; > - `requested_bounds` removed - not used anymore; > - `window_configure` incorporated in `set_bounds` with `gtk_window_move` and `gtk_window_resize`; > - `process_net_wm_property` is a work-around for Unity only (added a check if Unity - but it can probably be removed at some point) > - `restack` split in `to_front()` and `to_back()` to conform to managed code; This pull request has now been integrated. Changeset: 0c03a411 Author: Thiago Milczarek Sayao URL: https://git.openjdk.org/jfx/commit/0c03a411655047a393862eda937408aa90fc3fa9 Stats: 750 lines in 5 files changed: 175 ins; 434 del; 141 mod 8260528: Clean glass-gtk sizing and positioning code Reviewed-by: jvos, kcr ------------- PR: https://git.openjdk.org/jfx/pull/915 From hmeda at openjdk.org Mon Apr 10 18:02:03 2023 From: hmeda at openjdk.org (Hima Bindu Meda) Date: Mon, 10 Apr 2023 18:02:03 GMT Subject: [jfx20u] RFR: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 Message-ID: Clean Backport.This pull request contains a backport of commit [a264435d](https://github.com/openjdk/jfx/commit/a264435dccba6ec386548f76f1ace095d943f4ca) from the [openjdk/jfx](https://git.openjdk.org/jfx) repository. ------------- Commit messages: - Backport a264435dccba6ec386548f76f1ace095d943f4ca Changes: https://git.openjdk.org/jfx20u/pull/12/files Webrev: https://webrevs.openjdk.org/?repo=jfx20u&pr=12&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8282359 Stats: 9 lines in 1 file changed: 9 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jfx20u/pull/12.diff Fetch: git fetch https://git.openjdk.org/jfx20u.git pull/12/head:pull/12 PR: https://git.openjdk.org/jfx20u/pull/12 From jbhaskar at openjdk.org Mon Apr 10 18:02:00 2023 From: jbhaskar at openjdk.org (Jay Bhaskar) Date: Mon, 10 Apr 2023 18:02:00 GMT Subject: [jfx20u] RFR: 8286089: Intermittent WebKit build failure on macOS in JavaScriptCore Message-ID: clean backport to jfx20u. The fix solves the build issue on the macOx11_64 machine. It fixes the intermittent build issue. The build issue occurs without the fix and does not occur with the fix. ------------- Commit messages: - Backport 810bd90d5089364067549b8ba299300bfd208357 Changes: https://git.openjdk.org/jfx20u/pull/11/files Webrev: https://webrevs.openjdk.org/?repo=jfx20u&pr=11&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8286089 Stats: 26 lines in 1 file changed: 26 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jfx20u/pull/11.diff Fetch: git fetch https://git.openjdk.org/jfx20u.git pull/11/head:pull/11 PR: https://git.openjdk.org/jfx20u/pull/11 From kizune at openjdk.org Mon Apr 10 18:59:22 2023 From: kizune at openjdk.org (Alexander Zuev) Date: Mon, 10 Apr 2023 18:59:22 GMT Subject: RFR: 8301312: Create implementation of NSAccessibilityButton protocol In-Reply-To: References: Message-ID: On Sat, 8 Apr 2023 14:16:57 GMT, Kevin Rushforth wrote: >> Add the common base component for all the new implementing native classes Change native peer creation to use the new base component The new code will instantiate new protocol implementation for the given role if it exists or an old one if it does not exist >> Added BUTTON role implementing class > > modules/javafx.graphics/src/main/java/com/sun/glass/ui/mac/MacAccessible.java line 807: > >> 805: if (this.peer == 0L) { >> 806: AccessibleRole role = (AccessibleRole) getAttribute(ROLE); >> 807: if (role == null) role = AccessibleRole.NODE; > > When would `role` be null? And if it is, is defaulting to `NODE` going to do the right thing once you implement the new a11y protocol for Node? It can be when customer creates a custom component that does not provide accessible attributes. With the new API that will be covered by the default implementation that will report some generic role. > modules/javafx.graphics/src/main/java/com/sun/glass/ui/mac/MacAccessible.java line 976: > >> 974: return -1; >> 975: } >> 976: > > This method is not used anywhere (even from native code). Yes, that was added as one of the ways to provide role to the initialization but i ended up by passing role as a string at the initialization phase so this method has to be removed. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1161988092 PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1161989719 From mstrauss at openjdk.org Mon Apr 10 19:21:17 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 10 Apr 2023 19:21:17 GMT Subject: RFR: JDK-8304439: Subscription based listeners [v2] In-Reply-To: <1ybACQTFTQ4PqtoPyikEJ0WM0i6p-Sou3BOBKOpCrrA=.fdfe08aa-9458-4e6b-a099-2331a89bf951@github.com> References: <1ybACQTFTQ4PqtoPyikEJ0WM0i6p-Sou3BOBKOpCrrA=.fdfe08aa-9458-4e6b-a099-2331a89bf951@github.com> Message-ID: On Mon, 27 Mar 2023 14:36:45 GMT, John Hendrikx wrote: >> Makes `Subscription` public (removing some of its methods that are unnecessary), and adds methods that can provide `Subscription`s in `ObservableValue`. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Move Subscription method for invalidations to Observable > > - moved Subscription class to the Observable package modules/javafx.base/src/main/java/javafx/beans/Observable.java line 107: > 105: * @since 21 > 106: */ > 107: default Subscription invalidations(Runnable subscriber) { I think re-using `InvalidationListener` may fit better into the existing JavaFX API: interface Observable { Subscription subscribe(InvalidationListener); } The method can then be overloaded for `ChangeListener`, `ListChangeListener`, `SetChangeListener`, and `MapChangeListener` as well. Doing so allows users to use the same functional interfaces they've used before with the `addListener`/`removeListener` APIs. As an added bonus, we don't need to allocate a wrapper for the listeners. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1069#discussion_r1162007648 From mstrauss at openjdk.org Mon Apr 10 19:26:22 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 10 Apr 2023 19:26:22 GMT Subject: RFR: JDK-8224260: ChangeListener not triggered when adding a new listener in invalidated method In-Reply-To: References: Message-ID: On Thu, 30 Mar 2023 21:53:48 GMT, John Hendrikx wrote: > Fixes three issues in ExpressionHelper: > > - Current Value was not retained when changing from SingleChange to Generic, this can lead to missed changes > - Current Value was not retained when changing from Generic to SingleChange, this can lead to missed changes > - Current Value was not cleared when last change listener was removed in Generic variant, resulting in an older value being referenced and not becoming eligible for GC until either a ChangeListener is added again, or sufficient InvalidationListeners are removed to switch to the SingleInvalidation implementation... This is a pretty straightforward change. I can confirm that it works as I would expect it to work. ------------- Marked as reviewed by mstrauss (Committer). PR Review: https://git.openjdk.org/jfx/pull/1078#pullrequestreview-1378015757 From kizune at openjdk.org Mon Apr 10 19:59:49 2023 From: kizune at openjdk.org (Alexander Zuev) Date: Mon, 10 Apr 2023 19:59:49 GMT Subject: RFR: 8301312: Create implementation of NSAccessibilityButton protocol In-Reply-To: References: Message-ID: On Sat, 8 Apr 2023 14:18:56 GMT, Kevin Rushforth wrote: >> Add the common base component for all the new implementing native classes Change native peer creation to use the new base component The new code will instantiate new protocol implementation for the given role if it exists or an old one if it does not exist >> Added BUTTON role implementing class > > modules/javafx.graphics/src/main/java/com/sun/glass/ui/mac/MacAccessible.java line 658: > >> 656: >> 657: MacAccessible() { >> 658: this.peer = _createGlassAccessible(); > > Now that you defer the creation of the `peer`, it might be safer to change line 798 to call `getNativeAccessible()` instead of accessing `peer` directly, in case `sendNotification()` is called before `getNativeAccessible()`, unless you know that this can't happen. Sure, makes sense. Fixing. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1162037171 From kizune at openjdk.org Mon Apr 10 20:03:05 2023 From: kizune at openjdk.org (Alexander Zuev) Date: Mon, 10 Apr 2023 20:03:05 GMT Subject: RFR: 8301312: Create implementation of NSAccessibilityButton protocol In-Reply-To: References: Message-ID: On Sat, 8 Apr 2023 14:19:34 GMT, Kevin Rushforth wrote: >> Add the common base component for all the new implementing native classes Change native peer creation to use the new base component The new code will instantiate new protocol implementation for the given role if it exists or an old one if it does not exist >> Added BUTTON role implementing class > > modules/javafx.graphics/src/main/native-glass/mac/a11y/AccessibleBase.h line 42: > >> 40: @end >> 41: >> 42: jmethodID jAccessibilityAttributeNames; > > Very minor: missing newline at end of file Fixing. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1162039432 From duke at openjdk.org Mon Apr 10 20:06:02 2023 From: duke at openjdk.org (Martin Fox) Date: Mon, 10 Apr 2023 20:06:02 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v8] In-Reply-To: References: Message-ID: <-CqX7QI0XAuX1JjWUugY8Yq0XSagxgrjL7Utz2xFacM=.be8f3cf0-0f07-48d9-b475-faee2bbc1985@github.com> > This PR adds code to ensure that KeyCodeCombinations match KeyEvents as expected by more accurately mapping from a Mac key code to a Java key code based on the user?s active keyboard layout (the existing code assumes a US QWERTY layout). The new code first identifies a set of Mac keys which can produce different characters based on the user?s keyboard layout. A Mac key code outside that area is processed exactly as before. For a key inside the layout-sensitive area the code calls UCKeyTranslate to translate the key to an unshifted ASCII character based on the active keyboard and uses that to determine the Java key code. > > When performing the reverse mapping for the Robot the code first uses the old QWERTY mapping to find a candidate key. If it lies in the layout-sensitive area the code then scans the entire area calling UCKeyTranslate until it finds a match. If the key lies outside the layout-sensitive area it?s processed exactly as before. > > There are multiple duplicates of these bugs logged against Mac applications built with JavaFX. > > https://bugs.openjdk.java.net/browse/JDK-8090257 Mac: Inconsistent KeyEvents with alternative keyboard layouts > https://bugs.openjdk.java.net/browse/JDK-8088120 [Accelerator, Mac] CMD + Z accelerator is not working with French keyboard > https://bugs.openjdk.java.net/browse/JDK-8087915 Mac: accelerator doesn't take into account azerty keyboard layout > https://bugs.openjdk.java.net/browse/JDK-8150709 Mac OSX and German Keyboard Layout (Y/Z) Martin Fox has updated the pull request incrementally with one additional commit since the last revision: Added Spanish to KeyboardTest and fixed related bug. Changes based on review feedback. ------------- Changes: - all: https://git.openjdk.org/jfx/pull/425/files - new: https://git.openjdk.org/jfx/pull/425/files/47b4eb86..3e6fc266 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=425&range=07 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=425&range=06-07 Stats: 65 lines in 3 files changed: 50 ins; 0 del; 15 mod Patch: https://git.openjdk.org/jfx/pull/425.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/425/head:pull/425 PR: https://git.openjdk.org/jfx/pull/425 From duke at openjdk.org Mon Apr 10 20:07:08 2023 From: duke at openjdk.org (Martin Fox) Date: Mon, 10 Apr 2023 20:07:08 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> References: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> Message-ID: On Wed, 5 Apr 2023 12:36:37 GMT, Jose Pereda wrote: >> Martin Fox has updated the pull request incrementally with one additional commit since the last revision: >> >> Added manual cross-platform keyboard handling test > > modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 195: > >> 193: } >> 194: >> 195: if (keyCode >= 0x00 && keyCode <= 0x32) > > Add a comment? like `// Null to [Space]` This are Mac virtual key code constants, not characters, so this covers the keyboard from 'A' to 'grave'. I added a comment clarifying this as well as the 0x5D to 0x5F range (which are JIS keys). I could change the numbers from hex to the symbolic constants defined in Events.h but keeping them in hex makes it easier to compare to the table. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1162042846 From duke at openjdk.org Mon Apr 10 20:11:56 2023 From: duke at openjdk.org (Martin Fox) Date: Mon, 10 Apr 2023 20:11:56 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> References: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> Message-ID: <5sDaRNZkwkFiDOrdDJiaEiaezScsETwzKpTYgdiOXnU=.7625c6a6-7399-4686-adf3-2c66c9b7e96c@github.com> On Wed, 5 Apr 2023 12:39:28 GMT, Jose Pereda wrote: >> Martin Fox has updated the pull request incrementally with one additional commit since the last revision: >> >> Added manual cross-platform keyboard handling test > > modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 195: > >> 193: } >> 194: >> 195: if (keyCode >= 0x00 && keyCode <= 0x32) > > out of curiosity, why not? > ` if ((keyCode >= 0x00 && keyCode <= 0x32) || (keyCode >= 0x5D && keyCode <= 0x5F))` No real reason, it was probably just easier to write it like this when I was originally going through the table and sorting out the ranges. I do prefer separating out conditionals when I can since it makes it easier to set debug breakpoints (not that that matters here). ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1162045857 From duke at openjdk.org Mon Apr 10 20:18:51 2023 From: duke at openjdk.org (Martin Fox) Date: Mon, 10 Apr 2023 20:18:51 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> References: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> Message-ID: On Wed, 5 Apr 2023 12:51:31 GMT, Jose Pereda wrote: >> Martin Fox has updated the pull request incrementally with one additional commit since the last revision: >> >> Added manual cross-platform keyboard handling test > > modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 473: > >> 471: // If the QWERTY key is in the layout sensitive area search the other keys in that >> 472: // area. We may not find a key so returning NO is possible. >> 473: for (unsigned short trialKey = 0x00; trialKey <= 0x7E; ++trialKey) > > I see this as a last resource, in case everything else failed so far. But I wonder if this could be slow? > Also given that keyCode in sensitive layout is true only for [0x00 - 0x32] and 0x5D, 0x5F, maybe you could improve this? This call is used by the Robot code and an accessibility feature (namely retrieving the `AXMenuItemCmdVirtualKey` property). Robots aren't built for speed but I will look into the accessibility side. To make significant gains in this code I would have to cache the results. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1162051937 From kcr at openjdk.org Mon Apr 10 20:33:48 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 10 Apr 2023 20:33:48 GMT Subject: RFR: 8301312: Create implementation of NSAccessibilityButton protocol In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 18:54:44 GMT, Alexander Zuev wrote: >> modules/javafx.graphics/src/main/java/com/sun/glass/ui/mac/MacAccessible.java line 807: >> >>> 805: if (this.peer == 0L) { >>> 806: AccessibleRole role = (AccessibleRole) getAttribute(ROLE); >>> 807: if (role == null) role = AccessibleRole.NODE; >> >> When would `role` be null? And if it is, is defaulting to `NODE` going to do the right thing once you implement the new a11y protocol for Node? > > It can be when customer creates a custom component that does not provide accessible attributes. With the new API that will be covered by the default implementation that will report some generic role. OK. It looks like a `null` here can only happen for an accessible object that _isn't_ a `Node`, since `Node.getAccessibleRole` already ensures that a null value is converted to `AccessibleRole.NODE`. As long as the default implementation (of `AccessibleRole.NODE`) does the right thing for an object that doesn't report a specific role and isn't a `Node`, what you have seems fine. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1084#discussion_r1162062701 From duke at openjdk.org Mon Apr 10 20:57:48 2023 From: duke at openjdk.org (Martin Fox) Date: Mon, 10 Apr 2023 20:57:48 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> References: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> Message-ID: On Wed, 5 Apr 2023 13:25:00 GMT, Jose Pereda wrote: >> Martin Fox has updated the pull request incrementally with one additional commit since the last revision: >> >> Added manual cross-platform keyboard handling test > > tests/manual/events/KeyboardTest.java line 458: > >> 456: GERMAN("German", KeyListBuilder.germanKeys()), >> 457: LATIN("Latin", KeyListBuilder.latinKeys()), >> 458: NON_LATIN("non-Latin", KeyListBuilder.nonLatinKeys()); > > How hard would be adding another languages to this test, like Spanish? I see that you already commented that the robot can't access dead keys (so no possible test for `?` for instance...)? I added Spanish and found a bug in this PR, I wasn't handling the inverted exclamation mark. I've added it and Euro to match the Windows code. I can't test the `?` key on the Spanish layout since there's no corresponding KeyCode. This applies to most (all?) characters that include a diacritic. Most dead keys do have KeyCodes so in theory a Robot could generate key press events for them. This might even work on Windows and Linux though I haven't tested it. I've prototyped the Mac code but I think that would be a separate PR. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1162080211 From kcr at openjdk.org Mon Apr 10 21:07:49 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 10 Apr 2023 21:07:49 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 07:23:28 GMT, John Hendrikx wrote: >> modules/javafx.graphics/src/main/java/com/sun/javafx/css/BitSet.java line 603: >> >>> 601: @Override >>> 602: public void removeListener(SetChangeListener setChangeListener) { >>> 603: if (setChangeListener != null) { >> >> Even if not explicitly specified for `ObservableSet.removeListener(SetChangeListener)`, implementations generally reject `null` arguments by throwing NPE. This is the default behavior of `SetListenerHelper`. > > I could remove these checks in this PR, or as part of the larger `BitSet` clean-up PR. The extra check doesn't break anything though, while this PR is mainly focused on fixing a long standing bug that everyone dealing with `ObservableSet` can encounter currently. I do not recommend making any changes to how null is treated as part of this PR. This PR, as it stands, is a simple bug fix, so this sort of change seems out of scope. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1162072862 From kcr at openjdk.org Mon Apr 10 21:07:46 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 10 Apr 2023 21:07:46 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: On Mon, 27 Mar 2023 14:24:42 GMT, John Hendrikx wrote: > BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. > > When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. > > This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. Looks good. ------------- Marked as reviewed by kcr (Lead). PR Review: https://git.openjdk.org/jfx/pull/1071#pullrequestreview-1378109599 From kcr at openjdk.org Mon Apr 10 21:07:52 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 10 Apr 2023 21:07:52 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: On Mon, 3 Apr 2023 06:29:58 GMT, Michael Strau? wrote: >> BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. >> >> When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. >> >> This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. > > modules/javafx.graphics/src/main/java/com/sun/javafx/css/BitSet.java line 617: > >> 615: @Override >> 616: public void removeListener(InvalidationListener invalidationListener) { >> 617: if (invalidationListener != null) { > > `Observable.removeListener(InvalidationListener)` is specified to reject `null` by throwing NPE. As with the earlier comment, any changes to the behavior of a null listener should be done separately and not part of this PR. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1162073741 From mstrauss at openjdk.org Mon Apr 10 21:16:48 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 10 Apr 2023 21:16:48 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: On Mon, 27 Mar 2023 14:24:42 GMT, John Hendrikx wrote: > BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. > > When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. > > This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. modules/javafx.graphics/src/shims/java/com/sun/javafx/css/BitSetShim.java line 95: > 93: } > 94: > 95: // Generated delegate methods: Very minor: these methods are not generated as part of the build process that would warrant pointing it out. modules/javafx.graphics/src/test/java/test/com/sun/javafx/css/BitSetTest.java line 1: > 1: package test.com.sun.javafx.css; This file is missing a copyright header. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1162093778 PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1162092570 From kcr at openjdk.org Mon Apr 10 21:46:51 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 10 Apr 2023 21:46:51 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 21:14:02 GMT, Michael Strau? wrote: >> BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. >> >> When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. >> >> This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. > > modules/javafx.graphics/src/shims/java/com/sun/javafx/css/BitSetShim.java line 95: > >> 93: } >> 94: >> 95: // Generated delegate methods: > > Very minor: these methods are not generated as part of the build process that would warrant pointing it out. Yes, it might be worth adding a comment to that effect. > modules/javafx.graphics/src/test/java/test/com/sun/javafx/css/BitSetTest.java line 1: > >> 1: package test.com.sun.javafx.css; > > This file is missing a copyright header. Ah, yes. Not sure how I missed that, but it will need to be fixed. Thanks for catching it. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1162113041 PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1162112257 From kcr at openjdk.org Mon Apr 10 21:46:48 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 10 Apr 2023 21:46:48 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: On Mon, 27 Mar 2023 14:24:42 GMT, John Hendrikx wrote: > BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. > > When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. > > This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. I'll re-approve once the missing copyright header is added. ------------- Changes requested by kcr (Lead). PR Review: https://git.openjdk.org/jfx/pull/1071#pullrequestreview-1378170488 From jhendrikx at openjdk.org Mon Apr 10 22:11:41 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 10 Apr 2023 22:11:41 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 20:45:22 GMT, Kevin Rushforth wrote: >> modules/javafx.graphics/src/main/java/com/sun/javafx/css/BitSet.java line 617: >> >>> 615: @Override >>> 616: public void removeListener(InvalidationListener invalidationListener) { >>> 617: if (invalidationListener != null) { >> >> `Observable.removeListener(InvalidationListener)` is specified to reject `null` by throwing NPE. > > As with the earlier comment, any changes to the behavior of a null listener should be done separately and not part of this PR. Alright, I'll file another ticket for that. The general state of this class is quite poor, as it does not follow any of the contracts of the interfaces it implements (including `Collection`, `Set` and `ObservableSet`). This is bad because even though this class is an implementation detail, it does get exposed as an `ObservableSet` via `Node#getPseudoClassStates`. Things that it violates for example are: node.getPseudoClassStates().retainAll(null); // no exception Or: node.getPseudoClassStates().retainAll(set2); // does nothing if set2 is not a BitSet Or: // fails, even if they're the same because `equals` assumes another BitSet node.getPseudoClassStates().equals(Set.of(PseudoClass.getPseudoClass("armed")); // works: Set.of(PseudoClass.getPseudoClass("armed")).equals(node.getPseudoClassStates()); Same goes for the hash code value; these are strictly defined for sets, but `BitSet` violates it causing problems when using these sets as keys. This causes numerous odd problems that I had to track down while implementing #1076 -- I can only assume very few people are using these API's in the wild. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1162126275 From kcr at openjdk.org Mon Apr 10 22:24:43 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 10 Apr 2023 22:24:43 GMT Subject: RFR: 8278938: [Win] Robot can target wrong key for punctuation and symbols [v3] In-Reply-To: References: Message-ID: On Fri, 7 Apr 2023 17:19:56 GMT, Martin Fox wrote: >> When processing a `WM_CHAR` event on an OEM key (punctuation, symbol, dead key) the glass code will dynamically query the key's unshifted character to determine the Java code to assign to it. This is necessary since the relationship between OEM key codes and the characters they generate varies from layout to layout. >> >> The Robot implementation was consulting a table which assumed a fixed relationship between Java codes and Windows key codes even for the OEM keys. The table was also missing entries for any Java code not on a US QWERTY layout, like PLUS. >> >> In this PR if we don't find the Java code in the table or if it maps to an OEM key (which may be wrong) we sweep through all the OEM keys looking for the matching Java code. > > Martin Fox has updated the pull request incrementally with one additional commit since the last revision: > > Updated license header copyrights The code changes look fine to me. I do have two minor points about code style. * Please enclose all single-line targets of `if`, etc., with curly braces. * I also recommend (but do not insist), that the opening curly brace the target block of `if`, etc., be on the same line as the `if`. We aren't quite as rigorous on code style in native code, but for code that isn't third-party, consistency is a good thing. modules/javafx.graphics/src/main/native-glass/win/KeyTable.cpp line 210: > 208: { > 209: if (oemKeys[i] == vkey) > 210: return true; Please enclose this in curly braces (or move the `return true;` to be on the same line as the `if`). modules/javafx.graphics/src/main/native-glass/win/KeyTable.cpp line 287: > 285: > 286: if (jkey == com_sun_glass_events_KeyEvent_VK_UNDEFINED) > 287: return; Same. ------------- PR Review: https://git.openjdk.org/jfx/pull/702#pullrequestreview-1376569816 PR Review Comment: https://git.openjdk.org/jfx/pull/702#discussion_r1160954017 PR Review Comment: https://git.openjdk.org/jfx/pull/702#discussion_r1160955289 From kcr at openjdk.org Mon Apr 10 22:43:40 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 10 Apr 2023 22:43:40 GMT Subject: RFR: 8278938: [Win] Robot can target wrong key for punctuation and symbols [v2] In-Reply-To: References: Message-ID: On Fri, 7 Apr 2023 18:28:28 GMT, Martin Fox wrote: >> PR looks good and works fine on Windows 11. >> >> I've tested the test attached to the JBS issue with a Spanish keyboard. It fails without the patch for `+`, `'`, `?`, and passes with it. >> >> There is a NPE if you press AltGr (with or without the patch): >> >> Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: keyCode must not be null >> at java.base/java.util.Objects.requireNonNull(Objects.java:233) >> at javafx.graphics at 21-internal/javafx.scene.robot.Robot.keyPress(Robot.java:92) >> at RobotKeySanityTest.lambda$userReleasedEvent$0(RobotKeySanityTest.java:121) >> ``` >> >> I wonder if RobotKeySanityTest could be part of the PR as a manual test? Same as in #694 > >> I wonder if RobotKeySanityTest could be part of the PR as a manual test? Same as in #694 > > The RobotKeySanityTest is tricky, it requires the user to press a lot of keys to get good coverage but can produce confusing results if the user presses certain keys, like AltGr. Windows treats AltGr as if you pressed Ctrl and Alt at the same time. This means the OS sends two events when you press the key and two more when you release it. This is confusing the RobotKeySanityTest which can only handle one press/release pair at a time. I'm not sure I can fix the test but will think about it. > > The KeyboardTest app that I recently added to PR #425 covers most of the same ground and avoids the problematic keys. The downside of KeyboardTest is that it only provides good coverage for specific layouts (I'll try to add Spanish) and provides the best coverage when run against multiple layouts which takes effort to set up. > > I've written an app that just logs key events as the user types and that would probably be a better candidate to attach to some PR. When something confusing happens with RobotKeySanityTest or KeyboardTest that's the app I pull up to diagnose what's going on (like I just did with AltGr). @beldenfox One more comment: since your branch is quite out of date, can you please merge in the latest upstream master? ------------- PR Comment: https://git.openjdk.org/jfx/pull/702#issuecomment-1502426741 From kcr at openjdk.org Mon Apr 10 22:44:42 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 10 Apr 2023 22:44:42 GMT Subject: RFR: 8301312: Create implementation of NSAccessibilityButton protocol In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 20:43:13 GMT, Alexander Zuev wrote: > Add the common base component for all the new implementing native classes Change native peer creation to use the new base component The new code will instantiate new protocol implementation for the given role if it exists or an old one if it does not exist > Added BUTTON role implementing class @azuev-java Can you enable GHA runs for your personal fork, so we can see test results in this PR (not that it will run any a11y tests, but it will at least do a quick sanity check build). ------------- PR Comment: https://git.openjdk.org/jfx/pull/1084#issuecomment-1502428074 From jhendrikx at openjdk.org Mon Apr 10 23:08:31 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 10 Apr 2023 23:08:31 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect [v2] In-Reply-To: References: Message-ID: > BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. > > When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. > > This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: - Change comment - Add copyright header ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1071/files - new: https://git.openjdk.org/jfx/pull/1071/files/018f4bf3..10d51da2 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1071&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1071&range=00-01 Stats: 26 lines in 2 files changed: 25 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1071.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1071/head:pull/1071 PR: https://git.openjdk.org/jfx/pull/1071 From jhendrikx at openjdk.org Mon Apr 10 23:10:41 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 10 Apr 2023 23:10:41 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect [v2] In-Reply-To: References: Message-ID: <-hSuZkQ_4jv60crIWR1b5Ti5ZGb8cNbghLmIOTO-gXs=.0fc28e70-359c-4ccc-b130-b8cad0501f58@github.com> On Mon, 10 Apr 2023 22:07:41 GMT, John Hendrikx wrote: >> As with the earlier comment, any changes to the behavior of a null listener should be done separately and not part of this PR. > > Alright, I'll file another ticket for that. The general state of this class is quite poor, as it does not follow any of the contracts of the interfaces it implements (including `Collection`, `Set` and `ObservableSet`). This is bad because even though this class is an implementation detail, it does get exposed as an `ObservableSet` via `Node#getPseudoClassStates`. Things that it violates for example are: > > node.getPseudoClassStates().retainAll(null); // no exception > > Or: > > node.getPseudoClassStates().retainAll(set2); // does nothing if set2 is not a BitSet > > Or: > > // fails, even if they're the same because `equals` assumes another BitSet > node.getPseudoClassStates().equals(Set.of(PseudoClass.getPseudoClass("armed")); > > // works: > Set.of(PseudoClass.getPseudoClass("armed")).equals(node.getPseudoClassStates()); > > Same goes for the hash code value; these are strictly defined for sets, but `BitSet` violates it causing problems when using these sets as keys. This causes numerous odd problems that I had to track down while implementing #1076 -- I can only assume very few people are using these API's in the wild. Filed https://bugs.openjdk.org/browse/JDK-8305816 so we don't forget. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1071#discussion_r1162156819 From kcr at openjdk.org Mon Apr 10 23:43:41 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Mon, 10 Apr 2023 23:43:41 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect [v2] In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 23:08:31 GMT, John Hendrikx wrote: >> BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. >> >> When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. >> >> This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. > > John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: > > - Change comment > - Add copyright header Marked as reviewed by kcr (Lead). ------------- PR Review: https://git.openjdk.org/jfx/pull/1071#pullrequestreview-1378254494 From mstrauss at openjdk.org Mon Apr 10 23:43:42 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 10 Apr 2023 23:43:42 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect [v2] In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 23:08:31 GMT, John Hendrikx wrote: >> BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. >> >> When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. >> >> This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. > > John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: > > - Change comment > - Add copyright header Marked as reviewed by mstrauss (Committer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1071#pullrequestreview-1378255436 From jhendrikx at openjdk.org Mon Apr 10 23:47:41 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 10 Apr 2023 23:47:41 GMT Subject: Integrated: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect In-Reply-To: References: Message-ID: On Mon, 27 Mar 2023 14:24:42 GMT, John Hendrikx wrote: > BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. > > When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. > > This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. This pull request has now been integrated. Changeset: 53959421 Author: John Hendrikx URL: https://git.openjdk.org/jfx/commit/5395942174073f25a7fa8f6ccf2fb4dc6604133a Stats: 252 lines in 3 files changed: 249 ins; 0 del; 3 mod 8304933: BitSet (used for CSS pseudo class states) listener management is incorrect Reviewed-by: kcr, mstrauss ------------- PR: https://git.openjdk.org/jfx/pull/1071 From duke at openjdk.org Mon Apr 10 23:55:51 2023 From: duke at openjdk.org (Martin Fox) Date: Mon, 10 Apr 2023 23:55:51 GMT Subject: RFR: 8278938: [Win] Robot can target wrong key for punctuation and symbols [v4] In-Reply-To: References: Message-ID: > When processing a `WM_CHAR` event on an OEM key (punctuation, symbol, dead key) the glass code will dynamically query the key's unshifted character to determine the Java code to assign to it. This is necessary since the relationship between OEM key codes and the characters they generate varies from layout to layout. > > The Robot implementation was consulting a table which assumed a fixed relationship between Java codes and Windows key codes even for the OEM keys. The table was also missing entries for any Java code not on a US QWERTY layout, like PLUS. > > In this PR if we don't find the Java code in the table or if it maps to an OEM key (which may be wrong) we sweep through all the OEM keys looking for the matching Java code. Martin Fox has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains five additional commits since the last revision: - Coding style consistency - Merge remote-tracking branch 'upstream/master' into winrobot - Updated license header copyrights - A Robot now correctly handles KeyCodes that aren't in the current layout - Robot now targets punctuation and symbol keys reliably ------------- Changes: - all: https://git.openjdk.org/jfx/pull/702/files - new: https://git.openjdk.org/jfx/pull/702/files/d0d7acab..d6063597 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=702&range=03 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=702&range=02-03 Stats: 1319721 lines in 14952 files changed: 713537 ins; 422213 del; 183971 mod Patch: https://git.openjdk.org/jfx/pull/702.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/702/head:pull/702 PR: https://git.openjdk.org/jfx/pull/702 From kcr at openjdk.org Tue Apr 11 00:03:55 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Tue, 11 Apr 2023 00:03:55 GMT Subject: RFR: 8278938: [Win] Robot can target wrong key for punctuation and symbols [v4] In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 23:55:51 GMT, Martin Fox wrote: >> When processing a `WM_CHAR` event on an OEM key (punctuation, symbol, dead key) the glass code will dynamically query the key's unshifted character to determine the Java code to assign to it. This is necessary since the relationship between OEM key codes and the characters they generate varies from layout to layout. >> >> The Robot implementation was consulting a table which assumed a fixed relationship between Java codes and Windows key codes even for the OEM keys. The table was also missing entries for any Java code not on a US QWERTY layout, like PLUS. >> >> In this PR if we don't find the Java code in the table or if it maps to an OEM key (which may be wrong) we sweep through all the OEM keys looking for the matching Java code. > > Martin Fox has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains five additional commits since the last revision: > > - Coding style consistency > - Merge remote-tracking branch 'upstream/master' into winrobot > - Updated license header copyrights > - A Robot now correctly handles KeyCodes that aren't in the current layout > - Robot now targets punctuation and symbol keys reliably Looks good. ------------- Marked as reviewed by kcr (Lead). PR Review: https://git.openjdk.org/jfx/pull/702#pullrequestreview-1378266182 From jbhaskar at openjdk.org Tue Apr 11 01:18:42 2023 From: jbhaskar at openjdk.org (Jay Bhaskar) Date: Tue, 11 Apr 2023 01:18:42 GMT Subject: [jfx20u] Integrated: 8286089: Intermittent WebKit build failure on macOS in JavaScriptCore In-Reply-To: References: Message-ID: <2GIPztZOEIr_7ZsK1EL4JP14LCwuJohpUXXfC7bLALc=.04ffaa5f-eeae-4434-8748-6fa5f1f6cf9a@github.com> On Mon, 10 Apr 2023 17:19:15 GMT, Jay Bhaskar wrote: > clean backport to jfx20u. The fix solves the build issue on the macOx11_64 machine. It fixes the intermittent build issue. The build issue occurs without the fix and does not occur with the fix. This pull request has now been integrated. Changeset: 727923ea Author: Jay Bhaskar URL: https://git.openjdk.org/jfx20u/commit/727923ead8cc5f6ccee58bda31e9bc1dc92e25c0 Stats: 26 lines in 1 file changed: 26 ins; 0 del; 0 mod 8286089: Intermittent WebKit build failure on macOS in JavaScriptCore Backport-of: 810bd90d5089364067549b8ba299300bfd208357 ------------- PR: https://git.openjdk.org/jfx20u/pull/11 From nlisker at openjdk.org Tue Apr 11 01:25:47 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Tue, 11 Apr 2023 01:25:47 GMT Subject: RFR: JDK-8224260: ChangeListener not triggered when adding a new listener in invalidated method In-Reply-To: References: Message-ID: On Thu, 30 Mar 2023 21:53:48 GMT, John Hendrikx wrote: > Fixes three issues in ExpressionHelper: > > - Current Value was not retained when changing from SingleChange to Generic, this can lead to missed changes > - Current Value was not retained when changing from Generic to SingleChange, this can lead to missed changes > - Current Value was not cleared when last change listener was removed in Generic variant, resulting in an older value being referenced and not becoming eligible for GC until either a ChangeListener is added again, or sufficient InvalidationListeners are removed to switch to the SingleInvalidation implementation... Looks good. Added a couple of comments about documentation. modules/javafx.base/src/main/java/com/sun/javafx/binding/ExpressionHelper.java line 1: > 1: /* I would write in the class doc a bit of an explanation on handling the current value here compared to the one in the observable, including why `ExpressionHelper` needs its own value and why when creating a new `ExpressionHelper` the value needs to be passed form the previous one and not taken from the observable (implying they are not the same). This is a fine point that can be overlooked easily that I think it worth documenting internally here. modules/javafx.base/src/test/java/test/com/sun/javafx/binding/ExpressionHelperTest.java line 673: > 671: p.set("b"); > 672: > 673: assertTrue(invalidated.get()); // true because it was added before called Maybe the comment be more specific with something like "true because the invalidation listener was added before it could be called"? Same for the other methods. ------------- PR Review: https://git.openjdk.org/jfx/pull/1078#pullrequestreview-1378296924 PR Review Comment: https://git.openjdk.org/jfx/pull/1078#discussion_r1162203751 PR Review Comment: https://git.openjdk.org/jfx/pull/1078#discussion_r1162192266 From nlisker at openjdk.org Tue Apr 11 01:39:46 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Tue, 11 Apr 2023 01:39:46 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v3] In-Reply-To: <_vF5M6ym104Ah0W0tpby9uv-GZsS0nwpVtwoktKSa1M=.96ea4378-0cb5-496a-bd22-ce797468127c@github.com> References: <-LO-7b7wb0L55OTfiObMEeAAXn3PjPSe5v7bVq2EMsc=.48b6595b-543d-4630-aec6-f6c11b597851@github.com> <_vF5M6ym104Ah0W0tpby9uv-GZsS0nwpVtwoktKSa1M=.96ea4378-0cb5-496a-bd22-ce797468127c@github.com> Message-ID: On Mon, 10 Apr 2023 00:14:31 GMT, John Hendrikx wrote: > Well, I am just following the specification here, but JavaFX itself isn't... > > We may need to make a decision here. JavaFX is not consistent itself where it applies `equals` and where it uses reference equality: Alright, so this is fine for this PR. As for the equality test, we will need to revise the implementation note (that I wrote) to explain correctly what is used where and consider the changes you proposed. ReactFX uses `equals` internally, and it was very hard to debug why changing to its observables caused a change in the behavior, which is why I'm extra careful about this issue. My idea was to allow the user to specify their own equality checks when registering a listener, but that requires a lot more thought. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1056#issuecomment-1502561838 From nlisker at gmail.com Tue Apr 11 01:43:38 2023 From: nlisker at gmail.com (Nir Lisker) Date: Tue, 11 Apr 2023 04:43:38 +0300 Subject: Update javadoc tool version? Message-ID: Hi, I noticed that the JDK's javadoc contains a 'NEW' section [1], but JavaFX's docs don't have it. Do we need to update the javadoc tool? [1] https://docs.oracle.com/en/java/javase/19/docs/api/new-list.html - Nir -------------- next part -------------- An HTML attachment was scrubbed... URL: From hmeda at openjdk.org Tue Apr 11 04:03:42 2023 From: hmeda at openjdk.org (Hima Bindu Meda) Date: Tue, 11 Apr 2023 04:03:42 GMT Subject: [jfx20u] Integrated: 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 17:21:34 GMT, Hima Bindu Meda wrote: > Clean Backport.This pull request contains a backport of commit [a264435d](https://github.com/openjdk/jfx/commit/a264435dccba6ec386548f76f1ace095d943f4ca) from the [openjdk/jfx](https://git.openjdk.org/jfx) repository. This pull request has now been integrated. Changeset: cb434d12 Author: Hima Bindu Meda URL: https://git.openjdk.org/jfx20u/commit/cb434d124e3e888928c2c800d3b5b6cbe28a9bf7 Stats: 9 lines in 1 file changed: 9 ins; 0 del; 0 mod 8282359: Intermittent WebKit build failure on Windows: C1090: PDB API call failed, error code 23 Backport-of: a264435dccba6ec386548f76f1ace095d943f4ca ------------- PR: https://git.openjdk.org/jfx20u/pull/12 From jhendrikx at openjdk.org Tue Apr 11 07:32:44 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Tue, 11 Apr 2023 07:32:44 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v3] In-Reply-To: References: <-LO-7b7wb0L55OTfiObMEeAAXn3PjPSe5v7bVq2EMsc=.48b6595b-543d-4630-aec6-f6c11b597851@github.com> <_vF5M6ym104Ah0W0tpby9uv-GZsS0nwpVtwoktKSa1M=.96ea4378-0cb5-496a-bd22-ce797468127c@github.com> Message-ID: On Tue, 11 Apr 2023 01:36:48 GMT, Nir Lisker wrote: > > Well, I am just following the specification here, but JavaFX itself isn't... > > We may need to make a decision here. JavaFX is not consistent itself where it applies `equals` and where it uses reference equality: > > Alright, so this is fine for this PR. > > As for the equality test, we will need to revise the implementation note (that I wrote) to explain correctly what is used where and consider the changes you proposed. ReactFX uses `equals` internally, and it was very hard to debug why changing to its observables caused a change in the behavior, which is why I'm extra careful about this issue. My idea was to allow the user to specify their own equality checks when registering a listener, but that requires a lot more thought. Well at least you only described what JavaFX has been doing all along then. I am convinced that reference equality is the right way to go; ~unwanted~ equal changes can be ignored in the change listener (or something that wraps your change listener). An ~unwanted~ equal change would only occur when the type involved is mutable, which you would have to ignore at your own peril -- once you have the wrong instance, you will either see changes to the "old" instance that you don't want, or not pick up on any direct changes to the new instance that you decided to ignore. Luckily, most stuff JavaFX is doing is using immutable types. It gets in trouble a bit with all the Set/List/Map wrappers, which is what the test pointed out (you need to use `InvalidationListener`s there, as they still fire on reference equality changes). ------------- PR Comment: https://git.openjdk.org/jfx/pull/1056#issuecomment-1502825318 From jhendrikx at openjdk.org Tue Apr 11 07:57:56 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Tue, 11 Apr 2023 07:57:56 GMT Subject: RFR: JDK-8224260: ChangeListener not triggered when adding a new listener in invalidated method [v2] In-Reply-To: References: Message-ID: > Fixes three issues in ExpressionHelper: > > - Current Value was not retained when changing from SingleChange to Generic, this can lead to missed changes > - Current Value was not retained when changing from Generic to SingleChange, this can lead to missed changes > - Current Value was not cleared when last change listener was removed in Generic variant, resulting in an older value being referenced and not becoming eligible for GC until either a ChangeListener is added again, or sufficient InvalidationListeners are removed to switch to the SingleInvalidation implementation... John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Doc improvements ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1078/files - new: https://git.openjdk.org/jfx/pull/1078/files/8fb56715..c4cb0c12 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1078&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1078&range=00-01 Stats: 15 lines in 2 files changed: 11 ins; 0 del; 4 mod Patch: https://git.openjdk.org/jfx/pull/1078.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1078/head:pull/1078 PR: https://git.openjdk.org/jfx/pull/1078 From nlisker at openjdk.org Tue Apr 11 08:31:53 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Tue, 11 Apr 2023 08:31:53 GMT Subject: RFR: JDK-8224260: ChangeListener not triggered when adding a new listener in invalidated method [v2] In-Reply-To: References: Message-ID: On Tue, 11 Apr 2023 07:57:56 GMT, John Hendrikx wrote: >> Fixes three issues in ExpressionHelper: >> >> - Current Value was not retained when changing from SingleChange to Generic, this can lead to missed changes >> - Current Value was not retained when changing from Generic to SingleChange, this can lead to missed changes >> - Current Value was not cleared when last change listener was removed in Generic variant, resulting in an older value being referenced and not becoming eligible for GC until either a ChangeListener is added again, or sufficient InvalidationListeners are removed to switch to the SingleInvalidation implementation... > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Doc improvements Marked as reviewed by nlisker (Reviewer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1078#pullrequestreview-1378710264 From jpereda at openjdk.org Tue Apr 11 08:33:56 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Tue, 11 Apr 2023 08:33:56 GMT Subject: RFR: 8278938: [Win] Robot can target wrong key for punctuation and symbols [v4] In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 23:55:51 GMT, Martin Fox wrote: >> When processing a `WM_CHAR` event on an OEM key (punctuation, symbol, dead key) the glass code will dynamically query the key's unshifted character to determine the Java code to assign to it. This is necessary since the relationship between OEM key codes and the characters they generate varies from layout to layout. >> >> The Robot implementation was consulting a table which assumed a fixed relationship between Java codes and Windows key codes even for the OEM keys. The table was also missing entries for any Java code not on a US QWERTY layout, like PLUS. >> >> In this PR if we don't find the Java code in the table or if it maps to an OEM key (which may be wrong) we sweep through all the OEM keys looking for the matching Java code. > > Martin Fox has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains five additional commits since the last revision: > > - Coding style consistency > - Merge remote-tracking branch 'upstream/master' into winrobot > - Updated license header copyrights > - A Robot now correctly handles KeyCodes that aren't in the current layout > - Robot now targets punctuation and symbol keys reliably Marked as reviewed by jpereda (Reviewer). ------------- PR Review: https://git.openjdk.org/jfx/pull/702#pullrequestreview-1378714800 From kcr at openjdk.org Tue Apr 11 11:09:51 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Tue, 11 Apr 2023 11:09:51 GMT Subject: RFR: JDK-8224260: ChangeListener not triggered when adding a new listener in invalidated method [v2] In-Reply-To: References: Message-ID: On Tue, 11 Apr 2023 07:57:56 GMT, John Hendrikx wrote: >> Fixes three issues in ExpressionHelper: >> >> - Current Value was not retained when changing from SingleChange to Generic, this can lead to missed changes >> - Current Value was not retained when changing from Generic to SingleChange, this can lead to missed changes >> - Current Value was not cleared when last change listener was removed in Generic variant, resulting in an older value being referenced and not becoming eligible for GC until either a ChangeListener is added again, or sufficient InvalidationListeners are removed to switch to the SingleInvalidation implementation... > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Doc improvements Marked as reviewed by kcr (Lead). ------------- PR Review: https://git.openjdk.org/jfx/pull/1078#pullrequestreview-1378997682 From kcr at openjdk.org Tue Apr 11 11:31:51 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Tue, 11 Apr 2023 11:31:51 GMT Subject: RFR: 8269593: Different fontname on macos [v2] In-Reply-To: References: <7yKAEMYVzjEexg8QT14Z8Fn_uoZ219e82DaQipSSiFk=.504733aa-d66b-4698-a012-ad97da4cf99d@github.com> Message-ID: On Tue, 29 Jun 2021 14:20:30 GMT, Johan Vos wrote: >> Make sure the returned fullName of a created font matches the requested name. Since the name is used as a key/identifier in some cases, some internal code relies on this. >> Added a test to check the case of "System Font Regular" on MacOS, which fails before and succeeds after the patch. > > Johan Vos has updated the pull request incrementally with one additional commit since the last revision: > > rename test I am closing this PR now that #1067 is integrated. ------------- PR Comment: https://git.openjdk.org/jfx/pull/553#issuecomment-1503158767 From kcr at openjdk.org Tue Apr 11 11:31:52 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Tue, 11 Apr 2023 11:31:52 GMT Subject: Withdrawn: 8269593: Different fontname on macos In-Reply-To: <7yKAEMYVzjEexg8QT14Z8Fn_uoZ219e82DaQipSSiFk=.504733aa-d66b-4698-a012-ad97da4cf99d@github.com> References: <7yKAEMYVzjEexg8QT14Z8Fn_uoZ219e82DaQipSSiFk=.504733aa-d66b-4698-a012-ad97da4cf99d@github.com> Message-ID: On Tue, 29 Jun 2021 14:00:08 GMT, Johan Vos wrote: > Make sure the returned fullName of a created font matches the requested name. Since the name is used as a key/identifier in some cases, some internal code relies on this. > Added a test to check the case of "System Font Regular" on MacOS, which fails before and succeeds after the patch. This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jfx/pull/553 From kcr at openjdk.org Tue Apr 11 11:32:46 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Tue, 11 Apr 2023 11:32:46 GMT Subject: RFR: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: <9AkX_puthOSBlHiBmpmmfkp1Q4QuyBx4kM-B_2hvyzo=.1430c2f1-8bcf-4129-b591-9213dfa16517@github.com> References: <9AkX_puthOSBlHiBmpmmfkp1Q4QuyBx4kM-B_2hvyzo=.1430c2f1-8bcf-4129-b591-9213dfa16517@github.com> Message-ID: On Sat, 26 Jun 2021 15:40:47 GMT, Johan Vos wrote: > [Mac only] register system fonts. > Fix for JDK-8246104 > > The list of available fonts returned by CTFontCollectionCreateFromAvailableFonts does not contain internal fonts (at least not by default, although this is not documented). By registering font(s) (files), those fonts become available in the returned list. > The CT Glyph processing might assign internal fonts to a glyph, and since we lookup the requested font in this list, we fail if the list doesn't contain the font. > This PR registers all fonts in the system library so that they become available. This is not creating additional Java objects or overhead, as it almost directly invokes `CTFontManagerRegisterFontsForURL` via `CTFontFile.registerFont(String fontfile)` I am closing this PR now that #1067 is integrated. ------------- PR Comment: https://git.openjdk.org/jfx/pull/547#issuecomment-1503159130 From kcr at openjdk.org Tue Apr 11 11:32:47 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Tue, 11 Apr 2023 11:32:47 GMT Subject: Withdrawn: 8246104: Some complex text doesn't render correctly on macOS In-Reply-To: <9AkX_puthOSBlHiBmpmmfkp1Q4QuyBx4kM-B_2hvyzo=.1430c2f1-8bcf-4129-b591-9213dfa16517@github.com> References: <9AkX_puthOSBlHiBmpmmfkp1Q4QuyBx4kM-B_2hvyzo=.1430c2f1-8bcf-4129-b591-9213dfa16517@github.com> Message-ID: On Sat, 26 Jun 2021 15:40:47 GMT, Johan Vos wrote: > [Mac only] register system fonts. > Fix for JDK-8246104 > > The list of available fonts returned by CTFontCollectionCreateFromAvailableFonts does not contain internal fonts (at least not by default, although this is not documented). By registering font(s) (files), those fonts become available in the returned list. > The CT Glyph processing might assign internal fonts to a glyph, and since we lookup the requested font in this list, we fail if the list doesn't contain the font. > This PR registers all fonts in the system library so that they become available. This is not creating additional Java objects or overhead, as it almost directly invokes `CTFontManagerRegisterFontsForURL` via `CTFontFile.registerFont(String fontfile)` This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.org/jfx/pull/547 From aghaisas at openjdk.org Tue Apr 11 11:44:49 2023 From: aghaisas at openjdk.org (Ajit Ghaisas) Date: Tue, 11 Apr 2023 11:44:49 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu [v2] In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 08:32:33 GMT, Karthik P K wrote: >> When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. >> >> Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. >> >> Added system test to validate the fix. > > Karthik P K has updated the pull request incrementally with one additional commit since the last revision: > > Renamed package to match coding convention Overall the fix looks good. I have one minor spacing comment. modules/javafx.controls/src/main/java/javafx/scene/control/skin/ContextMenuSkin.java line 204: > 202: root.idProperty().unbind(); > 203: root.styleProperty().unbind(); > 204: if(root instanceof ContextMenuContent) { Minor: add a space between `if` and `(` ------------- PR Review: https://git.openjdk.org/jfx/pull/1082#pullrequestreview-1377183234 PR Review Comment: https://git.openjdk.org/jfx/pull/1082#discussion_r1161500279 From jhendrikx at openjdk.org Tue Apr 11 12:03:42 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Tue, 11 Apr 2023 12:03:42 GMT Subject: Integrated: JDK-8224260: ChangeListener not triggered when adding a new listener in invalidated method In-Reply-To: References: Message-ID: On Thu, 30 Mar 2023 21:53:48 GMT, John Hendrikx wrote: > Fixes three issues in ExpressionHelper: > > - Current Value was not retained when changing from SingleChange to Generic, this can lead to missed changes > - Current Value was not retained when changing from Generic to SingleChange, this can lead to missed changes > - Current Value was not cleared when last change listener was removed in Generic variant, resulting in an older value being referenced and not becoming eligible for GC until either a ChangeListener is added again, or sufficient InvalidationListeners are removed to switch to the SingleInvalidation implementation... This pull request has now been integrated. Changeset: fb63b26f Author: John Hendrikx URL: https://git.openjdk.org/jfx/commit/fb63b26fc5fe277e5c95d16aedd7703b64fe2253 Stats: 127 lines in 2 files changed: 101 ins; 10 del; 16 mod 8224260: ChangeListener not triggered when adding a new listener in invalidated method Reviewed-by: kcr, nlisker ------------- PR: https://git.openjdk.org/jfx/pull/1078 From kpk at openjdk.org Tue Apr 11 12:18:52 2023 From: kpk at openjdk.org (Karthik P K) Date: Tue, 11 Apr 2023 12:18:52 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu [v3] In-Reply-To: References: Message-ID: <2Jf34r29-QJVoSf6hVRsxiSD038Qlp8XvxSpshveayY=.e53f74cb-182a-4e09-b9c1-21a32eed9ff2@github.com> > When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. > > Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. > > Added system test to validate the fix. Karthik P K has updated the pull request incrementally with two additional commits since the last revision: - Add space between if and ( - Address review comments ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1082/files - new: https://git.openjdk.org/jfx/pull/1082/files/1e91b094..cba6a855 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1082&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1082&range=01-02 Stats: 2 lines in 2 files changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jfx/pull/1082.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1082/head:pull/1082 PR: https://git.openjdk.org/jfx/pull/1082 From kpk at openjdk.org Tue Apr 11 12:18:55 2023 From: kpk at openjdk.org (Karthik P K) Date: Tue, 11 Apr 2023 12:18:55 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu [v3] In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 07:21:21 GMT, Ajit Ghaisas wrote: >> Karthik P K has updated the pull request incrementally with two additional commits since the last revision: >> >> - Add space between if and ( >> - Address review comments > > modules/javafx.controls/src/main/java/javafx/scene/control/skin/ContextMenuSkin.java line 204: > >> 202: root.idProperty().unbind(); >> 203: root.styleProperty().unbind(); >> 204: if(root instanceof ContextMenuContent) { > > Minor: add a space between `if` and `(` Updated code. Please check ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1082#discussion_r1162728540 From angorya at openjdk.org Tue Apr 11 15:15:51 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Tue, 11 Apr 2023 15:15:51 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu [v3] In-Reply-To: <2Jf34r29-QJVoSf6hVRsxiSD038Qlp8XvxSpshveayY=.e53f74cb-182a-4e09-b9c1-21a32eed9ff2@github.com> References: <2Jf34r29-QJVoSf6hVRsxiSD038Qlp8XvxSpshveayY=.e53f74cb-182a-4e09-b9c1-21a32eed9ff2@github.com> Message-ID: On Tue, 11 Apr 2023 12:18:52 GMT, Karthik P K wrote: >> When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. >> >> Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. >> >> Added system test to validate the fix. > > Karthik P K has updated the pull request incrementally with two additional commits since the last revision: > > - Add space between if and ( > - Address review comments modules/javafx.controls/src/main/java/javafx/scene/control/skin/ContextMenuSkin.java line 206: > 204: if (root instanceof ContextMenuContent) { > 205: ((ContextMenuContent)root).disposeListeners(); > 206: } We could use if (root instanceof ContextMenuContent cm) { cm.disposeListeners(); } pattern ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1082#discussion_r1162960698 From hmeda at openjdk.org Tue Apr 11 17:12:41 2023 From: hmeda at openjdk.org (Hima Bindu Meda) Date: Tue, 11 Apr 2023 17:12:41 GMT Subject: [jfx20u] Integrated: 8301009: Update libxml2 to 2.10.3 Message-ID: Clean Backport.This pull request contains a backport of commit [935c7b79](https://github.com/openjdk/jfx/commit/935c7b797d79407d741735324313684617d1292d) from the [openjdk/jfx](https://git.openjdk.org/jfx) repository. ------------- Commit messages: - Backport 935c7b797d79407d741735324313684617d1292d Changes: https://git.openjdk.org/jfx20u/pull/13/files Webrev: https://webrevs.openjdk.org/?repo=jfx20u&pr=13&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8301009 Stats: 6301 lines in 80 files changed: 1128 ins; 4562 del; 611 mod Patch: https://git.openjdk.org/jfx20u/pull/13.diff Fetch: git fetch https://git.openjdk.org/jfx20u.git pull/13/head:pull/13 PR: https://git.openjdk.org/jfx20u/pull/13 From hmeda at openjdk.org Tue Apr 11 17:12:43 2023 From: hmeda at openjdk.org (Hima Bindu Meda) Date: Tue, 11 Apr 2023 17:12:43 GMT Subject: [jfx20u] Integrated: 8301009: Update libxml2 to 2.10.3 In-Reply-To: References: Message-ID: On Tue, 11 Apr 2023 17:03:51 GMT, Hima Bindu Meda wrote: > Clean Backport.This pull request contains a backport of commit [935c7b79](https://github.com/openjdk/jfx/commit/935c7b797d79407d741735324313684617d1292d) from the [openjdk/jfx](https://git.openjdk.org/jfx) repository. This pull request has now been integrated. Changeset: 608d19fe Author: Hima Bindu Meda URL: https://git.openjdk.org/jfx20u/commit/608d19fe1407ad7426287b26e69c228fa8a3b3db Stats: 6301 lines in 80 files changed: 1128 ins; 4562 del; 611 mod 8301009: Update libxml2 to 2.10.3 Backport-of: 935c7b797d79407d741735324313684617d1292d ------------- PR: https://git.openjdk.org/jfx20u/pull/13 From angorya at openjdk.org Tue Apr 11 18:30:47 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Tue, 11 Apr 2023 18:30:47 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect [v2] In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 23:08:31 GMT, John Hendrikx wrote: >> BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. >> >> When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. >> >> This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. > > John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: > > - Change comment > - Add copyright header too late, but this code gives off 2 warnings: Description Resource Location The type parameter T is hiding the type T BitSetShim.java line 133 The type parameter T is hiding the type T BitSetShim.java line 173 ------------- PR Comment: https://git.openjdk.org/jfx/pull/1071#issuecomment-1503886315 From duke at openjdk.org Tue Apr 11 18:52:48 2023 From: duke at openjdk.org (Martin Fox) Date: Tue, 11 Apr 2023 18:52:48 GMT Subject: Integrated: 8278938: [Win] Robot can target wrong key for punctuation and symbols In-Reply-To: References: Message-ID: On Thu, 23 Dec 2021 20:50:53 GMT, Martin Fox wrote: > When processing a `WM_CHAR` event on an OEM key (punctuation, symbol, dead key) the glass code will dynamically query the key's unshifted character to determine the Java code to assign to it. This is necessary since the relationship between OEM key codes and the characters they generate varies from layout to layout. > > The Robot implementation was consulting a table which assumed a fixed relationship between Java codes and Windows key codes even for the OEM keys. The table was also missing entries for any Java code not on a US QWERTY layout, like PLUS. > > In this PR if we don't find the Java code in the table or if it maps to an OEM key (which may be wrong) we sweep through all the OEM keys looking for the matching Java code. This pull request has now been integrated. Changeset: 3d6f3288 Author: Martin Fox Committer: Kevin Rushforth URL: https://git.openjdk.org/jfx/commit/3d6f3288ace658900e9af11792d7dd444ad55277 Stats: 181 lines in 3 files changed: 114 ins; 57 del; 10 mod 8278938: [Win] Robot can target wrong key for punctuation and symbols Reviewed-by: jpereda, kcr ------------- PR: https://git.openjdk.org/jfx/pull/702 From kcr at openjdk.org Tue Apr 11 18:55:46 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Tue, 11 Apr 2023 18:55:46 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect [v2] In-Reply-To: References: Message-ID: On Tue, 11 Apr 2023 18:27:51 GMT, Andy Goryachev wrote: > too late, but this code gives off 2 warnings: The warnings are from Eclipse? The signature of this method matches the interface method from `Set` so the warnings are surprising. If you think it's a legitimate warning, then can you file a (low priority) test bug to track this? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1071#issuecomment-1503928158 From angorya at openjdk.org Tue Apr 11 19:01:51 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Tue, 11 Apr 2023 19:01:51 GMT Subject: RFR: JDK-8304933: BitSet (used for CSS pseudo class states) listener management is incorrect [v2] In-Reply-To: References: Message-ID: On Mon, 10 Apr 2023 23:08:31 GMT, John Hendrikx wrote: >> BitSet uses the SetListenerHelper abstraction to prevent allocating the listener arrays. >> >> When removing listeners, the newly returned listener helper (which may be different from the one called) is not reassigned. This effectively means that removing the listener does not happen. >> >> This fix correctly assigns the potentially changed SetListenerHelper instance to BitSet's helper field after listener removal. > > John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: > > - Change comment > - Add copyright header In Set, the type is different: Set but toArray(T[]). created [JDK-8305867](https://bugs.openjdk.org/browse/JDK-8305867) ------------- PR Comment: https://git.openjdk.org/jfx/pull/1071#issuecomment-1503942582 From jvos at openjdk.org Tue Apr 11 19:49:43 2023 From: jvos at openjdk.org (Johan Vos) Date: Tue, 11 Apr 2023 19:49:43 GMT Subject: RFR: 8087370: [odroid] Monocle: Touch is still broken on Odroid In-Reply-To: <8r1cERIcJeZVLWYcG3EqWV7zKEoDqtLLgqBVHlPIUyI=.9f7e72c8-de1a-49f6-9df2-8d6a5f46174a@github.com> References: <8r1cERIcJeZVLWYcG3EqWV7zKEoDqtLLgqBVHlPIUyI=.9f7e72c8-de1a-49f6-9df2-8d6a5f46174a@github.com> Message-ID: On Wed, 13 Oct 2021 10:52:40 GMT, Fabian Wolter wrote: > There are sometimes multitouch events detected, when only a single touch should be detected under certain conditions. This lead to touch events on previous touch positions. > > The referenced bug is closed with "won't fix" with the justification it would be platform specific. But this is not correct. It affects all Linux platforms combined with a touch controller, which sends the touch events in an uncommon, but valid(!), order. > > We encountered this problem with the touch controller ILI2511 with firmware V6000_V1 in the Tianma display TM070JVHG33. This patch fixes the problem. It is the same patch attached to above bug report. I'll have a look at it next week. I think this is an area where we would need more tests. Can you add a test for this that fails before the patch and succeeds after? ------------- PR Comment: https://git.openjdk.org/jfx/pull/641#issuecomment-1503999241 From angorya at openjdk.org Tue Apr 11 20:51:52 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Tue, 11 Apr 2023 20:51:52 GMT Subject: RFR: 8305867: BitSetShim: The type parameter T is hiding the type T warning Message-ID: Fixed minor warnings in Eclipse. ------------- Commit messages: - 8305867: BitSetShim: The type parameter T is hiding the type T warning Changes: https://git.openjdk.org/jfx/pull/1086/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1086&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8305867 Stats: 3 lines in 1 file changed: 0 ins; 0 del; 3 mod Patch: https://git.openjdk.org/jfx/pull/1086.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1086/head:pull/1086 PR: https://git.openjdk.org/jfx/pull/1086 From jhendrikx at openjdk.org Wed Apr 12 04:57:45 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Wed, 12 Apr 2023 04:57:45 GMT Subject: RFR: 8305867: BitSetShim: The type parameter T is hiding the type T warning In-Reply-To: References: Message-ID: On Tue, 11 Apr 2023 20:46:37 GMT, Andy Goryachev wrote: > Fixed minor warnings in Eclipse. Marked as reviewed by jhendrikx (Committer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1086#pullrequestreview-1380481855 From kpk at openjdk.org Wed Apr 12 05:08:46 2023 From: kpk at openjdk.org (Karthik P K) Date: Wed, 12 Apr 2023 05:08:46 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu [v4] In-Reply-To: References: Message-ID: > When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. > > Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. > > Added system test to validate the fix. Karthik P K has updated the pull request incrementally with one additional commit since the last revision: Address code review ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1082/files - new: https://git.openjdk.org/jfx/pull/1082/files/cba6a855..f0d1e7f7 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1082&range=03 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1082&range=02-03 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.org/jfx/pull/1082.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1082/head:pull/1082 PR: https://git.openjdk.org/jfx/pull/1082 From kpk at openjdk.org Wed Apr 12 05:08:48 2023 From: kpk at openjdk.org (Karthik P K) Date: Wed, 12 Apr 2023 05:08:48 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu [v3] In-Reply-To: References: <2Jf34r29-QJVoSf6hVRsxiSD038Qlp8XvxSpshveayY=.e53f74cb-182a-4e09-b9c1-21a32eed9ff2@github.com> Message-ID: On Tue, 11 Apr 2023 15:04:27 GMT, Andy Goryachev wrote: >> Karthik P K has updated the pull request incrementally with two additional commits since the last revision: >> >> - Add space between if and ( >> - Address review comments > > modules/javafx.controls/src/main/java/javafx/scene/control/skin/ContextMenuSkin.java line 206: > >> 204: if (root instanceof ContextMenuContent) { >> 205: ((ContextMenuContent)root).disposeListeners(); >> 206: } > > We could use > > > if (root instanceof ContextMenuContent cm) { > cm.disposeListeners(); > } > > > pattern Updated code. Please check ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1082#discussion_r1163608480 From aghaisas at openjdk.org Wed Apr 12 06:16:45 2023 From: aghaisas at openjdk.org (Ajit Ghaisas) Date: Wed, 12 Apr 2023 06:16:45 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu [v4] In-Reply-To: References: Message-ID: On Wed, 12 Apr 2023 05:08:46 GMT, Karthik P K wrote: >> When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. >> >> Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. >> >> Added system test to validate the fix. > > Karthik P K has updated the pull request incrementally with one additional commit since the last revision: > > Address code review Marked as reviewed by aghaisas (Reviewer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1082#pullrequestreview-1380584353 From arapte at openjdk.org Wed Apr 12 07:25:45 2023 From: arapte at openjdk.org (Ambarish Rapte) Date: Wed, 12 Apr 2023 07:25:45 GMT Subject: RFR: 8301312: Create implementation of NSAccessibilityButton protocol In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 20:43:13 GMT, Alexander Zuev wrote: > Add the common base component for all the new implementing native classes Change native peer creation to use the new base component The new code will instantiate new protocol implementation for the given role if it exists or an old one if it does not exist > Added BUTTON role implementing class I noticed two behavioral change, when VoiceOver is running. - Focus Rectangle: A Black (focus) rectangle is drawn around a focused control, or an item that has Accessibility focus. This seems correct and offers more visual information. - Control + Option + space key and only space key can perform an action on two different controls at the same time. Steps to observe: 1. Launch Ensemble and run Timeline sample from Animation section. 2. Notice there are four buttons. 3. At launch the button Start gets focus and focus rectangle. 4. Press Space or Control+Option+Space button, both would trigger same Start button. 5. Press tab once, the focus moves to Pause button. 6. Press and hold Control+Option and press right arrow key two times. 7. The black focus rectangle moves to Restart button but Pause button retains the focus. 8. Pressing space button would trigger Pause button and 9. Pressing Control+Option+Space button would trigger Restart button. => I am not sure if this is expected behavior. => Similar behavior is not observed with a simple AWT sample with three buttons added to Frame. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1084#issuecomment-1504791569 From michaelstrau2 at gmail.com Wed Apr 12 07:26:07 2023 From: michaelstrau2 at gmail.com (=?UTF-8?Q?Michael_Strau=C3=9F?=) Date: Wed, 12 Apr 2023 09:26:07 +0200 Subject: Concatenated observable lists Message-ID: The JavaFX collections framework offers the `FXCollections.concat(ObservableList...)` method, which creates a new modifiable list that contains a concatenated snapshot of the source lists, backed by an `ArrayList`. However, when the source lists are changed, the concatenated list is not updated. I propose to add `FXCollections.concatenatedObservableList(ObservableList...)`, which creates an unmodifiable collection view onto the source lists that represents the concatenation of all source elements. When any of the source lists are changed, the change is also reflected in the concatenated view. This would add a useful capability to the JavaFX collections framework which has been requested a number of times [0] [1], and is currently only available via a third-party library [2]. A draft PR is available here: https://github.com/openjdk/jfx/pull/1087 [0] https://stackoverflow.com/questions/37524662/how-to-concatenate-observable-lists-in-javafx [1] https://bugs.openjdk.org/browse/JDK-8164626 [2] https://github.com/tobiasdiez/EasyBind#concat-lists-of-observable-lists From kcr at openjdk.org Wed Apr 12 11:09:55 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Wed, 12 Apr 2023 11:09:55 GMT Subject: RFR: 8305867: BitSetShim: The type parameter T is hiding the type T warning In-Reply-To: References: Message-ID: On Tue, 11 Apr 2023 20:46:37 GMT, Andy Goryachev wrote: > Fixed minor warnings in Eclipse. Marked as reviewed by kcr (Lead). ------------- PR Review: https://git.openjdk.org/jfx/pull/1086#pullrequestreview-1381070368 From angorya at openjdk.org Wed Apr 12 15:03:46 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Wed, 12 Apr 2023 15:03:46 GMT Subject: Integrated: 8305867: BitSetShim: The type parameter T is hiding the type T warning In-Reply-To: References: Message-ID: On Tue, 11 Apr 2023 20:46:37 GMT, Andy Goryachev wrote: > Fixed minor warnings in Eclipse. This pull request has now been integrated. Changeset: 4d7aaa48 Author: Andy Goryachev URL: https://git.openjdk.org/jfx/commit/4d7aaa485a0eebc39329a0ca0febdf6399f8012f Stats: 3 lines in 1 file changed: 0 ins; 0 del; 3 mod 8305867: BitSetShim: The type parameter T is hiding the type T warning Reviewed-by: jhendrikx, kcr ------------- PR: https://git.openjdk.org/jfx/pull/1086 From angorya at openjdk.org Wed Apr 12 15:14:05 2023 From: angorya at openjdk.org (Andy Goryachev) Date: Wed, 12 Apr 2023 15:14:05 GMT Subject: RFR: 8088594: NullPointerException on showing submenu of a contextmenu [v4] In-Reply-To: References: Message-ID: On Wed, 12 Apr 2023 05:08:46 GMT, Karthik P K wrote: >> When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. >> >> Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. >> >> Added system test to validate the fix. > > Karthik P K has updated the pull request incrementally with one additional commit since the last revision: > > Address code review Marked as reviewed by angorya (Committer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1082#pullrequestreview-1381545124 From arapte at openjdk.org Wed Apr 12 15:19:58 2023 From: arapte at openjdk.org (Ambarish Rapte) Date: Wed, 12 Apr 2023 15:19:58 GMT Subject: RFR: 8284542: Missing attribute for state of CheckBox in CheckBoxTreeItem Message-ID: Issue: CheckBoxTreeItem extends TreeItem and adds a CheckBox. The state of this CheckBox is not visible to an accessibility client application. If we analyze a simple program that contains a CheckBoxTreeItem using a windows application "Accessibility Insights for Window", we can notice that toggle state of CheckBox is not exposed. Fix: Include the [Toggle Control Pattern](https://learn.microsoft.com/en-us/windows/win32/winauto/uiauto-implementingtoggle) in Accessibility information of a CheckBoxTreeItem in addition to the patterns that are used for a TreeItem. Verification: On Windows: Do the following with and without the fix. 1. Run the sample program attached to JBS issue. 2. Launch "Accessibility Insights for Window" 3. Observe that patterns section for each item 4. Select / de-select the CheckBoxes and observe the patterns section for correctness of toggle state. ------------- Commit messages: - Add CheckBoxTreeItem role and TOGGLE_STATE attribute Changes: https://git.openjdk.org/jfx/pull/1088/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1088&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8284542 Stats: 109 lines in 5 files changed: 102 ins; 0 del; 7 mod Patch: https://git.openjdk.org/jfx/pull/1088.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1088/head:pull/1088 PR: https://git.openjdk.org/jfx/pull/1088 From jpereda at openjdk.org Wed Apr 12 15:43:31 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Wed, 12 Apr 2023 15:43:31 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v8] In-Reply-To: <-CqX7QI0XAuX1JjWUugY8Yq0XSagxgrjL7Utz2xFacM=.be8f3cf0-0f07-48d9-b475-faee2bbc1985@github.com> References: <-CqX7QI0XAuX1JjWUugY8Yq0XSagxgrjL7Utz2xFacM=.be8f3cf0-0f07-48d9-b475-faee2bbc1985@github.com> Message-ID: On Mon, 10 Apr 2023 20:06:02 GMT, Martin Fox wrote: >> This PR adds code to ensure that KeyCodeCombinations match KeyEvents as expected by more accurately mapping from a Mac key code to a Java key code based on the user?s active keyboard layout (the existing code assumes a US QWERTY layout). The new code first identifies a set of Mac keys which can produce different characters based on the user?s keyboard layout. A Mac key code outside that area is processed exactly as before. For a key inside the layout-sensitive area the code calls UCKeyTranslate to translate the key to an unshifted ASCII character based on the active keyboard and uses that to determine the Java key code. >> >> When performing the reverse mapping for the Robot the code first uses the old QWERTY mapping to find a candidate key. If it lies in the layout-sensitive area the code then scans the entire area calling UCKeyTranslate until it finds a match. If the key lies outside the layout-sensitive area it?s processed exactly as before. >> >> There are multiple duplicates of these bugs logged against Mac applications built with JavaFX. >> >> https://bugs.openjdk.java.net/browse/JDK-8090257 Mac: Inconsistent KeyEvents with alternative keyboard layouts >> https://bugs.openjdk.java.net/browse/JDK-8088120 [Accelerator, Mac] CMD + Z accelerator is not working with French keyboard >> https://bugs.openjdk.java.net/browse/JDK-8087915 Mac: accelerator doesn't take into account azerty keyboard layout >> https://bugs.openjdk.java.net/browse/JDK-8150709 Mac OSX and German Keyboard Layout (Y/Z) > > Martin Fox has updated the pull request incrementally with one additional commit since the last revision: > > Added Spanish to KeyboardTest and fixed related bug. Changes based on review feedback. Looks good, just a minor comment modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 458: > 456: BOOL GetMacKey(jint javaKeyCode, unsigned short *outMacKeyCode) > 457: { > 458: if (javaKeyCode == com_sun_glass_events_KeyEvent_VK_UNDEFINED) Please, add curly braces to the if expressions modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 475: > 473: // The table only covers US QWERTY so it's missing entries like PLUS that > 474: // don't appear on that layout. > 475: if (found && !macKeyCodeIsLayoutSensitive(*outMacKeyCode)) curly braces ------------- PR Review: https://git.openjdk.org/jfx/pull/425#pullrequestreview-1381580818 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1164306284 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1164306537 From jpereda at openjdk.org Wed Apr 12 15:43:34 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Wed, 12 Apr 2023 15:43:34 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: References: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> Message-ID: On Mon, 10 Apr 2023 20:04:45 GMT, Martin Fox wrote: >> modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 195: >> >>> 193: } >>> 194: >>> 195: if (keyCode >= 0x00 && keyCode <= 0x32) >> >> Add a comment? like `// Null to [Space]` > > This are Mac virtual key code constants, not characters, so this covers the keyboard from 'A' to 'grave'. I added a comment clarifying this as well as the 0x5D to 0x5F range (which are JIS keys). I could change the numbers from hex to the symbolic constants defined in Events.h but keeping them in hex makes it easier to compare to the table. Ok, good that you clarify this. >> modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 195: >> >>> 193: } >>> 194: >>> 195: if (keyCode >= 0x00 && keyCode <= 0x32) >> >> out of curiosity, why not? >> ` if ((keyCode >= 0x00 && keyCode <= 0x32) || (keyCode >= 0x5D && keyCode <= 0x5F))` > > No real reason, it was probably just easier to write it like this when I was originally going through the table and sorting out the ranges. I do prefer separating out conditionals when I can since it makes it easier to set debug breakpoints (not that that matters here). okay, no problem >> tests/manual/events/KeyboardTest.java line 458: >> >>> 456: GERMAN("German", KeyListBuilder.germanKeys()), >>> 457: LATIN("Latin", KeyListBuilder.latinKeys()), >>> 458: NON_LATIN("non-Latin", KeyListBuilder.nonLatinKeys()); >> >> How hard would be adding another languages to this test, like Spanish? I see that you already commented that the robot can't access dead keys (so no possible test for `?` for instance...)? > > I added Spanish and found a bug in this PR, I wasn't handling the inverted exclamation mark. I've added it and Euro to match the Windows code. > > I can't test the `?` key on the Spanish layout since there's no corresponding KeyCode. This applies to most (all?) characters that include a diacritic. > > Most dead keys do have KeyCodes so in theory a Robot could generate key press events for them. This might even work on Windows and Linux though I haven't tested it. I've prototyped the Mac code but I think that would be a separate PR. Thanks for adding Spanish, I've tested it successfully. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1164303135 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1164304142 PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1164309229 From jpereda at openjdk.org Wed Apr 12 15:43:39 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Wed, 12 Apr 2023 15:43:39 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> References: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> Message-ID: On Wed, 5 Apr 2023 12:38:36 GMT, Jose Pereda wrote: >> Martin Fox has updated the pull request incrementally with one additional commit since the last revision: >> >> Added manual cross-platform keyboard handling test > > modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 198: > >> 196: return YES; >> 197: >> 198: if (keyCode >= 0x5D && keyCode <= 0x5F) > > same: `'' to ']'` okay, fixed ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1164304706 From kevin.rushforth at oracle.com Wed Apr 12 16:14:37 2023 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Wed, 12 Apr 2023 09:14:37 -0700 Subject: CFV: New OpenJFX Committer: Karthik P K Message-ID: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> I hereby nominate Karthik P K [1] to OpenJFX Committer. Karthik is a member of the JavaFX team at Oracle who has contributed 15 commits [2] to OpenJFX. Votes are due by April 26, 2023 at 17:00 UTC. Only current OpenJFX Committers [3] are eligible to vote on this nomination. Votes must be cast in the open by replying to this mailing list. For Lazy Consensus voting instructions, see [4]. Nomination to a project Committer is described in [5]. Thanks. -- Kevin [1] https://openjdk.org/census#kpk [2] https://github.com/openjdk/jfx/search?p=1&q=author-email%3Akpk%40openjdk.org&s=author-date&type=Commits https://github.com/openjdk/jfx/search?q=author-email%3Akarthik.p.k%40oracle.com&s=author-date&type=Commits https://github.com/openjdk/jfx/search?q=author-email%3Akarthikpk111%40gmail.com&s=author-date&type=Commits [3] https://openjdk.org/census#openjfx [4] https://openjdk.org/bylaws#lazy-consensus [5] https://openjdk.org/projects#project-committer From kpk at openjdk.org Wed Apr 12 16:15:42 2023 From: kpk at openjdk.org (Karthik P K) Date: Wed, 12 Apr 2023 16:15:42 GMT Subject: Integrated: 8088594: NullPointerException on showing submenu of a contextmenu In-Reply-To: References: Message-ID: On Thu, 6 Apr 2023 13:03:04 GMT, Karthik P K wrote: > When custom skin was loaded, the listeners added in `ContextMenuContent` class while loading the default skin were not removed. This was causing the NPE when outdated listeners were invoked. > > Updated the code to dispose listeners in the `dispose` method of `ContextMenuSkin` so that when new skin is loaded, listeners added in the old skin are removed. > > Added system test to validate the fix. This pull request has now been integrated. Changeset: f28896aa Author: Karthik P K Committer: Andy Goryachev URL: https://git.openjdk.org/jfx/commit/f28896aa63592a37e7f78263548f3b2d4f2bc381 Stats: 342 lines in 6 files changed: 324 ins; 17 del; 1 mod 8088594: NullPointerException on showing submenu of a contextmenu Reviewed-by: aghaisas, angorya ------------- PR: https://git.openjdk.org/jfx/pull/1082 From andy.goryachev at oracle.com Wed Apr 12 16:17:36 2023 From: andy.goryachev at oracle.com (Andy Goryachev) Date: Wed, 12 Apr 2023 16:17:36 +0000 Subject: CFV: New OpenJFX Committer: Karthik P K In-Reply-To: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> References: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> Message-ID: Vote: yes From: openjfx-dev on behalf of Kevin Rushforth Date: Wednesday, April 12, 2023 at 09:15 To: openjfx-dev , Karthik P K Subject: CFV: New OpenJFX Committer: Karthik P K I hereby nominate Karthik P K [1] to OpenJFX Committer. Karthik is a member of the JavaFX team at Oracle who has contributed 15 commits [2] to OpenJFX. Votes are due by April 26, 2023 at 17:00 UTC. Only current OpenJFX Committers [3] are eligible to vote on this nomination. Votes must be cast in the open by replying to this mailing list. For Lazy Consensus voting instructions, see [4]. Nomination to a project Committer is described in [5]. Thanks. -- Kevin [1] https://openjdk.org/census#kpk [2] https://github.com/openjdk/jfx/search?p=1&q=author-email%3Akpk%40openjdk.org&s=author-date&type=Commits https://github.com/openjdk/jfx/search?q=author-email%3Akarthik.p.k%40oracle.com&s=author-date&type=Commits https://github.com/openjdk/jfx/search?q=author-email%3Akarthikpk111%40gmail.com&s=author-date&type=Commits [3] https://openjdk.org/census#openjfx [4] https://openjdk.org/bylaws#lazy-consensus [5] https://openjdk.org/projects#project-committer -------------- next part -------------- An HTML attachment was scrubbed... URL: From kevin.rushforth at oracle.com Wed Apr 12 16:19:10 2023 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Wed, 12 Apr 2023 09:19:10 -0700 Subject: CFV: New OpenJFX Committer: Karthik P K In-Reply-To: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> References: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> Message-ID: Vote: YES On 4/12/2023 9:14 AM, Kevin Rushforth wrote: > I hereby nominate Karthik P K [1] to OpenJFX Committer. From kcr at openjdk.org Wed Apr 12 16:20:06 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Wed, 12 Apr 2023 16:20:06 GMT Subject: RFR: 8284542: Missing attribute for state of CheckBox in CheckBoxTreeItem In-Reply-To: References: Message-ID: <-PE-FSG3Ia-K4MCoPi7gFRmPbiqC76XG8Bn_AoQdRlI=.627e5181-efe8-494e-a579-6a617816a927@github.com> On Wed, 12 Apr 2023 15:13:25 GMT, Ambarish Rapte wrote: > Issue: > CheckBoxTreeItem extends TreeItem and adds a CheckBox. > The state of this CheckBox is not visible to an accessibility client application. > If we analyze a simple program that contains a CheckBoxTreeItem using a windows application "Accessibility Insights for Window", we can notice that toggle state of CheckBox is not exposed. > > Fix: > Include the [Toggle Control Pattern](https://learn.microsoft.com/en-us/windows/win32/winauto/uiauto-implementingtoggle) in Accessibility information of a CheckBoxTreeItem in addition to the patterns that are used for a TreeItem. > > Verification: > On Windows: Do the following with and without the fix. > 1. Run the sample program attached to JBS issue. > 2. Launch "Accessibility Insights for Window" > 3. Observe that patterns section for each item > 4. Select / de-select the CheckBoxes and observe the patterns section for correctness of toggle state. @azuev-java @andy-goryachev-oracle can you take a look at this as well? ------------- PR Comment: https://git.openjdk.org/jfx/pull/1088#issuecomment-1505561519 From john at status6.com Wed Apr 12 16:26:19 2023 From: john at status6.com (John Neffenger) Date: Wed, 12 Apr 2023 09:26:19 -0700 Subject: CFV: New OpenJFX Committer: Karthik P K In-Reply-To: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> References: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> Message-ID: <17440fd1-590a-0227-4630-8cf34f234f28@status6.com> Vote: YES On 4/12/23 9:14 AM, Kevin Rushforth wrote: > I hereby nominate Karthik P K [1] to OpenJFX Committer. From philip.race at oracle.com Wed Apr 12 16:45:31 2023 From: philip.race at oracle.com (Philip Race) Date: Wed, 12 Apr 2023 09:45:31 -0700 Subject: CFV: New OpenJFX Committer: Karthik P K In-Reply-To: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> References: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> Message-ID: Vote: yes -phil. From lkostyra at openjdk.org Wed Apr 12 16:57:25 2023 From: lkostyra at openjdk.org (Lukasz Kostyra) Date: Wed, 12 Apr 2023 16:57:25 GMT Subject: RFR: 8233955: VM crashes if more than one file are added to ClipboardContent via drag and drop Message-ID: Crashes started happening due to macOS DnD API change from macOS 10.14 onwards. 10.14 incrodues some [DnD constrains](https://developer.apple.com/documentation/macos-release-notes/appkit-release-notes-for-macos-10_14#Drag-and-Drop) which our DnD code happened to trigger on some occasions. Our code used deprecated `dragImage` API which since 10.14 had new requirement - each NSPasteboard item had to have a corresponding drag image. Not meeting this constraint raised an exception, which crashed the app. Since there was no possibility to add more drag images to `dragImage` API (it only took one NSImage as parameter) the code had to be rewritten - as such I upgraded it to new DnD API utilizing NSDraggingSession and related protocols. One side-effect of new DnD API is that it now modifies NSPasteboard for us - previous behavior was more "separated" from user code perspective (write items to pasteboard -> initiate a drag via `dragImage`). Manually updating NSPasteboard before calling `beginDraggingSessionWithItems` raised another exception related to NSPasteboard already having DnD-ed elements inside it. Some system tests, however, relied on that behavior and writing to NSPasteboard (`MacPasteboardShim.java` used in some tests creates a `Clipboard.DND` for test purposes). Since this path is in tests I assumed this behavior should stay and tried to make it as close to working as possible. Tests (including those using `MacPasteboardShim`) pass after my changes. Additionally, added a new manual test based on `DndTest.java` test which creates two temporary files and allows for testing faulty behavior. ------------- Commit messages: - Add DnD Multiple File manual test - Fix preview position; cleanup code - Add image previews and finish DnD code - Migrate DnD native code to DraggingSession API Changes: https://git.openjdk.org/jfx/pull/1089/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1089&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8233955 Stats: 438 lines in 8 files changed: 383 ins; 17 del; 38 mod Patch: https://git.openjdk.org/jfx/pull/1089.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1089/head:pull/1089 PR: https://git.openjdk.org/jfx/pull/1089 From lkostyra at openjdk.org Wed Apr 12 16:57:26 2023 From: lkostyra at openjdk.org (Lukasz Kostyra) Date: Wed, 12 Apr 2023 16:57:26 GMT Subject: RFR: 8233955: VM crashes if more than one file are added to ClipboardContent via drag and drop In-Reply-To: References: Message-ID: On Wed, 12 Apr 2023 16:50:38 GMT, Lukasz Kostyra wrote: > Crashes started happening due to macOS DnD API change from macOS 10.14 onwards. 10.14 incrodues some [DnD constrains](https://developer.apple.com/documentation/macos-release-notes/appkit-release-notes-for-macos-10_14#Drag-and-Drop) which our DnD code happened to trigger on some occasions. > > Our code used deprecated `dragImage` API which since 10.14 had new requirement - each NSPasteboard item had to have a corresponding drag image. Not meeting this constraint raised an exception, which crashed the app. Since there was no possibility to add more drag images to `dragImage` API (it only took one NSImage as parameter) the code had to be rewritten - as such I upgraded it to new DnD API utilizing NSDraggingSession and related protocols. > > One side-effect of new DnD API is that it now modifies NSPasteboard for us - previous behavior was more "separated" from user code perspective (write items to pasteboard -> initiate a drag via `dragImage`). Manually updating NSPasteboard before calling `beginDraggingSessionWithItems` raised another exception related to NSPasteboard already having DnD-ed elements inside it. Some system tests, however, relied on that behavior and writing to NSPasteboard (`MacPasteboardShim.java` used in some tests creates a `Clipboard.DND` for test purposes). Since this path is in tests I assumed this behavior should stay and tried to make it as close to working as possible. Tests (including those using `MacPasteboardShim`) pass after my changes. > > Additionally, added a new manual test based on `DndTest.java` test which creates two temporary files and allows for testing faulty behavior. I would especially like to ask for someone macOS-and-ObjC-proficient to take a look at this - ObjC is not my strongest suite and I'm not 100% sure whether I did not introduce any memory leaks or other issues. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1089#issuecomment-1505608558 From duke at openjdk.org Wed Apr 12 17:46:00 2023 From: duke at openjdk.org (Martin Fox) Date: Wed, 12 Apr 2023 17:46:00 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v7] In-Reply-To: References: <4HKq-lmTWw9gVb1N8rFIKFUK8IU2jYeeXksHD1C4B08=.114c3a54-bf16-4b95-b1b8-9c1b913d2ba0@github.com> Message-ID: On Mon, 10 Apr 2023 20:16:23 GMT, Martin Fox wrote: >> modules/javafx.graphics/src/main/native-glass/mac/GlassKey.m line 473: >> >>> 471: // If the QWERTY key is in the layout sensitive area search the other keys in that >>> 472: // area. We may not find a key so returning NO is possible. >>> 473: for (unsigned short trialKey = 0x00; trialKey <= 0x7E; ++trialKey) >> >> I see this as a last resource, in case everything else failed so far. But I wonder if this could be slow? >> Also given that keyCode in sensitive layout is true only for [0x00 - 0x32] and 0x5D, 0x5F, maybe you could improve this? > > This call is used by the Robot code and an accessibility feature (namely retrieving the `AXMenuItemCmdVirtualKey` property). Robots aren't built for speed but I will look into the accessibility side. To make significant gains in this code I would have to cache the results. The accessibility code only calls `GetMacKey` for menu items which use `KeyCodes` and are not character-based (the check is `!isCmdCharBased` in MacAccessible.java). This means menu items where the accelerator references a key like `Return`, `Home`, or `PgUp`. `GetMacKey` will resolve these using the old lookup table without invoking the new, slower code that scans the rest of the keyboard. So accessibility shouldn't see a performance hit. A Robot will be slower to send events for some keys but I don't think that's an issue. Currently those are the only two clients of this call. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/425#discussion_r1164454567 From mstrauss at openjdk.org Wed Apr 12 18:21:49 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Wed, 12 Apr 2023 18:21:49 GMT Subject: RFR: 8305925: Add concatenated list view Message-ID: The JavaFX collections framework offers the `FXCollections.concat(ObservableList...)` method, which creates a new modifiable list that contains a concatenated snapshot of the source lists, backed by an `ArrayList`. However, when the source lists are changed, the concatenated list is not updated. This PR adds `FXCollections.concatenatedObservableList(ObservableList...)`, which creates an _unmodifiable collection view_ onto the source lists that represents the concatenation of all source elements. When any of the source lists are changed, the change is also reflected in the concatenated view. ------------- Commit messages: - Added concatenated observable list Changes: https://git.openjdk.org/jfx/pull/1087/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1087&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8305925 Stats: 459 lines in 3 files changed: 448 ins; 3 del; 8 mod Patch: https://git.openjdk.org/jfx/pull/1087.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1087/head:pull/1087 PR: https://git.openjdk.org/jfx/pull/1087 From kcr at openjdk.org Wed Apr 12 18:48:21 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Wed, 12 Apr 2023 18:48:21 GMT Subject: RFR: 8305925: Add concatenated list view In-Reply-To: References: Message-ID: <-q0pp1RUtrtndPDEcLFjjWBwZXaX75B4ySP9fCPvbd0=.ae329c78-7bec-4f53-95d0-7e1765d3b305@github.com> On Wed, 12 Apr 2023 07:24:08 GMT, Michael Strau? wrote: > The JavaFX collections framework offers the `FXCollections.concat(ObservableList...)` method, which creates a new modifiable list that contains a concatenated snapshot of the source lists, backed by an `ArrayList`. However, when the source lists are changed, the concatenated list is not updated. > > This PR adds `FXCollections.concatenatedObservableList(ObservableList...)`, which creates an _unmodifiable collection view_ onto the source lists that represents the concatenation of all source elements. When any of the source lists are changed, the change is also reflected in the concatenated view. Moving to Draft since we haven't finished the discussion of whether we want this feature at this time, and what form it should take. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1087#issuecomment-1505760283 From michaelstrau2 at gmail.com Wed Apr 12 19:04:49 2023 From: michaelstrau2 at gmail.com (=?UTF-8?Q?Michael_Strau=C3=9F?=) Date: Wed, 12 Apr 2023 21:04:49 +0200 Subject: Promote addEventHandler/removeEventHandler to EventTarget interface In-Reply-To: References: Message-ID: I've created a draft PR with the proposed changes: https://github.com/openjdk/jfx/pull/1090 Adding event handler management methods to `EventTarget` greatly increases the usefulness of the event system for the reasons John and I mentioned earlier. I want to circle back to the compatibility issues that arise from the proposed change: In general, adding a default-implemented method to an existing interface is not in itself an incompatible change. However, compatibility issues can arise when the new interface method doesn't override, but clash with the erasure of a preexisting method on an implementation of that interface. This is exactly the issue we are facing, but the circumstances in which this matters are extremely limited: The affected classes are Menu, MenuItem, TreeColumnBase and TreeItem. All of these classes provide a version of `addEventHandler` and `removeEventHandler`, but in contast to all other implementations, the signature of the method is slightly different. While the usual signature is the following: void addEventHandler(EventType, EventHandler), the mentioned classes instead declare a method with this signature: void addEventHandler(EventType, EventHandler). Note that the event handler is parameterized as , not . This is most likely an oversight, since there doesn't seem to be a justification to restrict event handlers to exactly T. Changing the method signature to conform to the correct version is a binary-compatible change, since the erasure of both methods remains the same. However, it is not a source-compatible change. But the ways in which this source incompatibility manifests are very limited: Callers of the modified API are not affected, since T <= ? super T. This probably accounts for the vast majority of cases. Overriding implementations will fail to compile without changing the method signature. To summarize, here are the two cases where the proposed changes cause compatibility issuse: 1. Existing `EventTarget` implementations that add a non-overriding, but erasure-equal `addEventHandler` method. 2. Subclasses of Menu, MenuItem, TreeColumnBase, or TreeItem that override the `addEventHandler` method. The first case is the kind of risk that always comes with new default-implemented interface methods. In this case, I think this is where most of real-world compatibility problems could arise. The second case doesn't seem relevant to me, because I don't see a good reason why a subclass of Menu, MenuItem, TreeColumnBase, or TreeView would override the `addEventHandler`, ... methods. In the end, as with all additions to existing interfaces, we need to carefully consider the benefits of the enhancement against potential risks. In this case, I think the risks are quite low, while the benefits are very significant. On Tue, Mar 7, 2023 at 3:35?PM Kevin Rushforth wrote: > > An incompatible change in a fundamental interface such as EventTarget is > not something we would want to do, so any proposed changes will need to > retain compatibility (both binary and source). At a minimum, this means > that any newly added methods would need to have a default > implementation, and we would need to look closely at other aspects of > compatibility. > > -- Kevin > > > On 3/7/2023 1:24 AM, John Hendrikx wrote: > > Hi Michael, > > > > Did you file a JIRA issue for this one? > > > > I've recently also been doing some rewriting to use the Event system > > more. I'm removing custom Scene walking code (and looking at > > Node.getProperties) to do "event handling", and I've now discovered > > that it could be done quite a bit nicer by using the provided event > > mechanism. > > > > I've encountered a few things that annoy me about the event system: > > > > 1) I'm making use of Presentation classes (Models) that only associate > > with things in javafx.base (Event, EventTarget, Properties). These > > presentations need to register event handlers at some point, but this > > can only be done on Nodes; having this logic close to the Presentation > > code makes sense, but it would make them dependent on javafx.graphics; > > if I could do this via EventTarget, the dependency would not be needed. > > > > 2) When you fire an event (via Node.fireEvent for example), there is > > no feedback you can obtain whether the event was consumed or not as > > the final event is not returned to check `isConsumed` on (internal > > calls do have this information, but it is not exposed at the last step). > > > > 3) Related to 2), I think EventTarget could also have a method to > > dispatch events (so you can dispatch an event easily to any target, > > not just via the convenience method Node#fireEvent). See this ticket: > > https://bugs.openjdk.org/browse/JDK-8303209 > > > > Perhaps we can work together on this, or if you're not currently > > working on it I could take a stab at solving all of these issues. > > > > --John > > > > On 17/03/2022 21:01, Michael Strau? wrote: > >> I'm working on an application that uses the JavaFX event system > >> extensively, and I'm finding it quite hard to use common code for > >> event handler registrations. > >> > >> The problem is that the `EventTarget` interface contains no > >> addEventHandler/removeEventHandler methods, and as a consequence of > >> that, code that uses `EventTarget` ends up requiring lots of brittle > >> instanceof tests to call these methods on all the different > >> implementations of `EventTarget`. > >> > >> There are three buckets of `EventTarget` implementations: > >> > >> 1) Implementations that declare the following methods: > >> void addEventHandler(EventType, > >> EventHandler); > >> void removeEventHandler(EventType, > >> EventHandler); > >> void addEventFilter(EventType, EventHandler >> super T>); > >> void removeEventFilter(EventType, > >> EventHandler); > >> --> Node, Scene, Window, Transform, Task, Service > >> > >> 2) Implementations that declare the following methods: > >> void addEventHandler(EventType, > >> EventHandler); > >> void removeEventHandler(EventType, > >> EventHandler); > >> --> MenuItem, TreeItem, TableColumnBase > >> > >> (Note that the EventHandler argument ist parameterized as > >> EventHandler, not EventHandler as in the first set of > >> methods.) > >> > >> 3) Implementations that don't declare any methods to add or remove > >> event handlers: > >> --> Dialog, Tab > >> > >> > >> I think the situation can be improved by promoting the bucket 1 > >> methods to the `EventTarget` interface, so they can be used > >> consistently across all implementations of `EventTarget`. > >> > >> This works seamlessly for bucket 1 and bucket 3 implementations. > >> > >> With bucket 2, there's the problem that, inconsistently, the > >> EventHandler argument is not a lower-bounded wildcard. > >> Unfortunately, a method with an EventHandler parameter cannot > >> implement an interface method that expects EventHandler. > >> > >> However, since the erasure of the method remains the same, changing > >> the method signature would technically be a binary-compatible change. > >> > >> Do you think this is a useful improvement? > From duke at openjdk.org Wed Apr 12 20:10:54 2023 From: duke at openjdk.org (Martin Fox) Date: Wed, 12 Apr 2023 20:10:54 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v9] In-Reply-To: References: Message-ID: > This PR adds code to ensure that KeyCodeCombinations match KeyEvents as expected by more accurately mapping from a Mac key code to a Java key code based on the user?s active keyboard layout (the existing code assumes a US QWERTY layout). The new code first identifies a set of Mac keys which can produce different characters based on the user?s keyboard layout. A Mac key code outside that area is processed exactly as before. For a key inside the layout-sensitive area the code calls UCKeyTranslate to translate the key to an unshifted ASCII character based on the active keyboard and uses that to determine the Java key code. > > When performing the reverse mapping for the Robot the code first uses the old QWERTY mapping to find a candidate key. If it lies in the layout-sensitive area the code then scans the entire area calling UCKeyTranslate until it finds a match. If the key lies outside the layout-sensitive area it?s processed exactly as before. > > There are multiple duplicates of these bugs logged against Mac applications built with JavaFX. > > https://bugs.openjdk.java.net/browse/JDK-8090257 Mac: Inconsistent KeyEvents with alternative keyboard layouts > https://bugs.openjdk.java.net/browse/JDK-8088120 [Accelerator, Mac] CMD + Z accelerator is not working with French keyboard > https://bugs.openjdk.java.net/browse/JDK-8087915 Mac: accelerator doesn't take into account azerty keyboard layout > https://bugs.openjdk.java.net/browse/JDK-8150709 Mac OSX and German Keyboard Layout (Y/Z) Martin Fox has updated the pull request incrementally with one additional commit since the last revision: Coding style consistency (mostly) ------------- Changes: - all: https://git.openjdk.org/jfx/pull/425/files - new: https://git.openjdk.org/jfx/pull/425/files/3e6fc266..690709b9 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=425&range=08 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=425&range=07-08 Stats: 38 lines in 1 file changed: 17 ins; 2 del; 19 mod Patch: https://git.openjdk.org/jfx/pull/425.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/425/head:pull/425 PR: https://git.openjdk.org/jfx/pull/425 From ajit.ghaisas at oracle.com Thu Apr 13 03:49:05 2023 From: ajit.ghaisas at oracle.com (Ajit Ghaisas) Date: Thu, 13 Apr 2023 03:49:05 +0000 Subject: CFV: New OpenJFX Committer: Karthik P K In-Reply-To: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> References: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> Message-ID: Vote: YES Regards, Ajit > On 12-Apr-2023, at 9:44 PM, Kevin Rushforth wrote: > > I hereby nominate Karthik P K [1] to OpenJFX Committer. > > Karthik is a member of the JavaFX team at Oracle who has contributed 15 commits [2] to OpenJFX. > > Votes are due by April 26, 2023 at 17:00 UTC. > > Only current OpenJFX Committers [3] are eligible to vote on this nomination. Votes must be cast in the open by replying to this mailing list. > > For Lazy Consensus voting instructions, see [4]. Nomination to a project Committer is described in [5]. > > Thanks. > > -- Kevin > > > [1] https://openjdk.org/census#kpk > > [2] > https://github.com/openjdk/jfx/search?p=1&q=author-email%3Akpk%40openjdk.org&s=author-date&type=Commits > https://github.com/openjdk/jfx/search?q=author-email%3Akarthik.p.k%40oracle.com&s=author-date&type=Commits > https://github.com/openjdk/jfx/search?q=author-email%3Akarthikpk111%40gmail.com&s=author-date&type=Commits > > [3] https://openjdk.org/census#openjfx > > [4] https://openjdk.org/bylaws#lazy-consensus > > [5] https://openjdk.org/projects#project-committer > From jpereda at openjdk.org Thu Apr 13 07:47:56 2023 From: jpereda at openjdk.org (Jose Pereda) Date: Thu, 13 Apr 2023 07:47:56 GMT Subject: RFR: 8150709: Mac OSX and German Keyboard Layout (Y/Z) [v9] In-Reply-To: References: Message-ID: On Wed, 12 Apr 2023 20:10:54 GMT, Martin Fox wrote: >> This PR adds code to ensure that KeyCodeCombinations match KeyEvents as expected by more accurately mapping from a Mac key code to a Java key code based on the user?s active keyboard layout (the existing code assumes a US QWERTY layout). The new code first identifies a set of Mac keys which can produce different characters based on the user?s keyboard layout. A Mac key code outside that area is processed exactly as before. For a key inside the layout-sensitive area the code calls UCKeyTranslate to translate the key to an unshifted ASCII character based on the active keyboard and uses that to determine the Java key code. >> >> When performing the reverse mapping for the Robot the code first uses the old QWERTY mapping to find a candidate key. If it lies in the layout-sensitive area the code then scans the entire area calling UCKeyTranslate until it finds a match. If the key lies outside the layout-sensitive area it?s processed exactly as before. >> >> There are multiple duplicates of these bugs logged against Mac applications built with JavaFX. >> >> https://bugs.openjdk.java.net/browse/JDK-8090257 Mac: Inconsistent KeyEvents with alternative keyboard layouts >> https://bugs.openjdk.java.net/browse/JDK-8088120 [Accelerator, Mac] CMD + Z accelerator is not working with French keyboard >> https://bugs.openjdk.java.net/browse/JDK-8087915 Mac: accelerator doesn't take into account azerty keyboard layout >> https://bugs.openjdk.java.net/browse/JDK-8150709 Mac OSX and German Keyboard Layout (Y/Z) > > Martin Fox has updated the pull request incrementally with one additional commit since the last revision: > > Coding style consistency (mostly) Looks good to me! ------------- Marked as reviewed by jpereda (Reviewer). PR Review: https://git.openjdk.org/jfx/pull/425#pullrequestreview-1382830542 From michaelstrau2 at gmail.com Thu Apr 13 18:55:50 2023 From: michaelstrau2 at gmail.com (=?UTF-8?Q?Michael_Strau=C3=9F?=) Date: Thu, 13 Apr 2023 20:55:50 +0200 Subject: Content Graph Message-ID: I've previously proposed an enhancement to introduce a "document graph" to JavaFX that would solve a problem that many people have encountered over the years: https://mail.openjdk.org/pipermail/openjfx-dev/2022-June/034417.html In a nutshell, the problem is that the JavaFX scene graph is a black box in the presence of control skins, which makes it hard to reason about its structure. On top of that, several nodes that look like they are part of the scene graph (MenuItem or Tab) aren't scene graph nodes at all. 1) Content Graph We can solve this problem by adding a content graph. The content graph is a structure that comprises all content nodes of a scene. Content nodes represent the significant scene content, which exludes all nodes contributed by skins, but includes some of the aforementioned nodes that are not part of the scene graph. The content graph consists of two new interfaces that live in the `javafx.content` package: public interface ContentNode { ContentParent getContentParent(); Styleable lookupContent(String selector); Set lookupAllContent(String selector); } public interface ContentParent extends ContentNode { ObservableList getContentChildren(); } These interfaces are implemented by `javafx.scene.Node` and `javafx.scene.Parent`, but also by other classes like `MenuItem` or `Tab`. Using these interfaces, the content graph can be traversed in the same way as the scene graph. Consider the following program, which creates a simple user interface: var root = new VBox(); var menuBtn = new MenuButton(); menuBtn.getItems().add(new MenuItem("Item 1")); menuBtn.getItems().add(new MenuItem("Item 2", new Rectangle())); root.getChildren().add(menuBtn); root.getChildren().add(new Button("Button 1", new Rectangle())); root.getChildren().add(new Button("Button 2", new Circle())); Suppose a method `printSceneGraph(Node root)`, which traverses the scene graph and prints out the nodes it encounters. Here is the output before the UI is shown: javafx.scene.layout.VBox ....javafx.scene.control.MenuButton ....javafx.scene.control.Button ....javafx.scene.control.Button And here's the output of the same method, but after the UI is shown: javafx.scene.layout.VBox ....javafx.scene.control.MenuButton ........javafx.scene.control.skin.MenuButtonSkinBase$MenuLabeledImpl ............com.sun.javafx.scene.control.LabeledText ........javafx.scene.layout.StackPane ............javafx.scene.layout.StackPane ....javafx.scene.control.Button ........javafx.scene.shape.Rectangle ........com.sun.javafx.scene.control.LabeledText ....javafx.scene.control.Button ........javafx.scene.shape.Circle ........com.sun.javafx.scene.control.LabeledText Note that the scene graph contains many more nodes after skins have been inflated, but it still doesn't contain the `MenuItem` instances. Now also suppose a method `printContentGraph(ContentNode root)`, which does the same as before, but works on the content graph. This is the output of that method: javafx.scene.layout.VBox ....javafx.scene.control.MenuButton ........javafx.content.Text ........javafx.scene.control.MenuItem ............javafx.content.Text ........javafx.scene.control.MenuItem ............javafx.content.Text ............javafx.scene.shape.Rectangle ....javafx.scene.control.Button ........javafx.content.Text ........javafx.scene.shape.Rectangle ....javafx.scene.control.Button ........javafx.content.Text ........javafx.scene.shape.Circle Note that the content graph is not affected by skins, and the output is the same whether the method is called before or after skin inflation. 2) Defining the Content Model The content graph consists of the content model of all participating controls. Implementors are responsible for defining the content model of a control by overriding the protected `buildContentModel` method, and adding the content that is significant for the control: public class SplitPane { ... @Override protected void buildContentModel( Consumer> contentModel) { super.buildContentModel(contentModel); contentModel.accept(getItems()); } ... } If a control subclass wants to extend the content model of an existing control, it simply overrides the `buildContentModel` method again as shown above. The content model of a subclass can only be extended, it can't be constrained. This is analogous to how a subclass of `Labeled` can only add new properties, but not remove the existing `Labeled.text` and `Labeled.graphic` properties. Note that if a custom control is not aware of the content graph and does not override the `buildContentModel` method, that's not an issue in itself; it simply means that the custom control will not contribute additional nodes to the content graph. 3) Operations on the Content Graph The content graph supports query operations on styleable nodes by adding two new lookup methods: `lookupContent` and `lookupAllContent`. This solves a problem that was discussed on the mailing list previously: https://mail.openjdk.org/pipermail/openjfx-dev/2022-December/037770.html The particular problem that was described in this email can be fixed simply by using `lookupAllContent` instead of `lookupAll`: window.getScene().getRoot().lookupAllContent(".split-pane") I'm interested in hearing your thoughts on this idea. If there is sufficient interest, I can contribute a PR for this enhancement. From andy.goryachev at oracle.com Thu Apr 13 19:44:08 2023 From: andy.goryachev at oracle.com (Andy Goryachev) Date: Thu, 13 Apr 2023 19:44:08 +0000 Subject: Promote addEventHandler/removeEventHandler to EventTarget interface In-Reply-To: References: Message-ID: I think this is a good idea, look what I had to do: https://github.com/openjdk/jfx/blob/f28896aa63592a37e7f78263548f3b2d4f2bc381/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/ListenerHelper.java#L396 I do agree with Kevin that we should look closely at any possible compatibility issues. I suspect the impact might be minimal due to the fact that it's highly unlikely for anyone to extend the EventTarget interface, but I could be wrong. -andy From: openjfx-dev on behalf of Michael Strau? Date: Wednesday, April 12, 2023 at 12:05 To: Kevin Rushforth Cc: openjfx-dev at openjdk.org Subject: Re: Promote addEventHandler/removeEventHandler to EventTarget interface I've created a draft PR with the proposed changes: https://github.com/openjdk/jfx/pull/1090 Adding event handler management methods to `EventTarget` greatly increases the usefulness of the event system for the reasons John and I mentioned earlier. I want to circle back to the compatibility issues that arise from the proposed change: In general, adding a default-implemented method to an existing interface is not in itself an incompatible change. However, compatibility issues can arise when the new interface method doesn't override, but clash with the erasure of a preexisting method on an implementation of that interface. This is exactly the issue we are facing, but the circumstances in which this matters are extremely limited: The affected classes are Menu, MenuItem, TreeColumnBase and TreeItem. All of these classes provide a version of `addEventHandler` and `removeEventHandler`, but in contast to all other implementations, the signature of the method is slightly different. While the usual signature is the following: void addEventHandler(EventType, EventHandler), the mentioned classes instead declare a method with this signature: void addEventHandler(EventType, EventHandler). Note that the event handler is parameterized as , not . This is most likely an oversight, since there doesn't seem to be a justification to restrict event handlers to exactly T. Changing the method signature to conform to the correct version is a binary-compatible change, since the erasure of both methods remains the same. However, it is not a source-compatible change. But the ways in which this source incompatibility manifests are very limited: Callers of the modified API are not affected, since T <= ? super T. This probably accounts for the vast majority of cases. Overriding implementations will fail to compile without changing the method signature. To summarize, here are the two cases where the proposed changes cause compatibility issuse: 1. Existing `EventTarget` implementations that add a non-overriding, but erasure-equal `addEventHandler` method. 2. Subclasses of Menu, MenuItem, TreeColumnBase, or TreeItem that override the `addEventHandler` method. The first case is the kind of risk that always comes with new default-implemented interface methods. In this case, I think this is where most of real-world compatibility problems could arise. The second case doesn't seem relevant to me, because I don't see a good reason why a subclass of Menu, MenuItem, TreeColumnBase, or TreeView would override the `addEventHandler`, ... methods. In the end, as with all additions to existing interfaces, we need to carefully consider the benefits of the enhancement against potential risks. In this case, I think the risks are quite low, while the benefits are very significant. On Tue, Mar 7, 2023 at 3:35?PM Kevin Rushforth wrote: > > An incompatible change in a fundamental interface such as EventTarget is > not something we would want to do, so any proposed changes will need to > retain compatibility (both binary and source). At a minimum, this means > that any newly added methods would need to have a default > implementation, and we would need to look closely at other aspects of > compatibility. > > -- Kevin > > > On 3/7/2023 1:24 AM, John Hendrikx wrote: > > Hi Michael, > > > > Did you file a JIRA issue for this one? > > > > I've recently also been doing some rewriting to use the Event system > > more. I'm removing custom Scene walking code (and looking at > > Node.getProperties) to do "event handling", and I've now discovered > > that it could be done quite a bit nicer by using the provided event > > mechanism. > > > > I've encountered a few things that annoy me about the event system: > > > > 1) I'm making use of Presentation classes (Models) that only associate > > with things in javafx.base (Event, EventTarget, Properties). These > > presentations need to register event handlers at some point, but this > > can only be done on Nodes; having this logic close to the Presentation > > code makes sense, but it would make them dependent on javafx.graphics; > > if I could do this via EventTarget, the dependency would not be needed. > > > > 2) When you fire an event (via Node.fireEvent for example), there is > > no feedback you can obtain whether the event was consumed or not as > > the final event is not returned to check `isConsumed` on (internal > > calls do have this information, but it is not exposed at the last step). > > > > 3) Related to 2), I think EventTarget could also have a method to > > dispatch events (so you can dispatch an event easily to any target, > > not just via the convenience method Node#fireEvent). See this ticket: > > https://bugs.openjdk.org/browse/JDK-8303209 > > > > Perhaps we can work together on this, or if you're not currently > > working on it I could take a stab at solving all of these issues. > > > > --John > > > > On 17/03/2022 21:01, Michael Strau? wrote: > >> I'm working on an application that uses the JavaFX event system > >> extensively, and I'm finding it quite hard to use common code for > >> event handler registrations. > >> > >> The problem is that the `EventTarget` interface contains no > >> addEventHandler/removeEventHandler methods, and as a consequence of > >> that, code that uses `EventTarget` ends up requiring lots of brittle > >> instanceof tests to call these methods on all the different > >> implementations of `EventTarget`. > >> > >> There are three buckets of `EventTarget` implementations: > >> > >> 1) Implementations that declare the following methods: > >> void addEventHandler(EventType, > >> EventHandler); > >> void removeEventHandler(EventType, > >> EventHandler); > >> void addEventFilter(EventType, EventHandler >> super T>); > >> void removeEventFilter(EventType, > >> EventHandler); > >> --> Node, Scene, Window, Transform, Task, Service > >> > >> 2) Implementations that declare the following methods: > >> void addEventHandler(EventType, > >> EventHandler); > >> void removeEventHandler(EventType, > >> EventHandler); > >> --> MenuItem, TreeItem, TableColumnBase > >> > >> (Note that the EventHandler argument ist parameterized as > >> EventHandler, not EventHandler as in the first set of > >> methods.) > >> > >> 3) Implementations that don't declare any methods to add or remove > >> event handlers: > >> --> Dialog, Tab > >> > >> > >> I think the situation can be improved by promoting the bucket 1 > >> methods to the `EventTarget` interface, so they can be used > >> consistently across all implementations of `EventTarget`. > >> > >> This works seamlessly for bucket 1 and bucket 3 implementations. > >> > >> With bucket 2, there's the problem that, inconsistently, the > >> EventHandler argument is not a lower-bounded wildcard. > >> Unfortunately, a method with an EventHandler parameter cannot > >> implement an interface method that expects EventHandler. > >> > >> However, since the erasure of the method remains the same, changing > >> the method signature would technically be a binary-compatible change. > >> > >> Do you think this is a useful improvement? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kpk at openjdk.org Fri Apr 14 07:42:57 2023 From: kpk at openjdk.org (Karthik P K) Date: Fri, 14 Apr 2023 07:42:57 GMT Subject: RFR: 8304831: TextFlow.hitTest.insertionIndex incorrect with surrogate pairs Message-ID: <3SN8lehcrLh8DJJ_qumZ_eGYw8y5aglKYVY9PPNquk0=.166e3e46-58c3-4fcf-b032-39f9fb9dd59b@github.com> Since surrogate pairs are internally considered as 2 characters and text field is null in `HitInfo` when `getInsertionIndex` is invoked from `TextFlow`, wrong insertion index was returned. Updated code to calculate insertion index in `getHitInfo` method of `PrismTextLayout` class when `hitTest` of trailing side of surrogate pair is requested. Since text runs are processed in this method already, calculating the insertion index in this method looks better than calculating in `getInsertionIndex` of `HitInfo` method. The latter approach also requires the text to be sent to `HitInfo` as parameter from the `hitTest` method of `TextFlow`. If the number of `Text` nodes in `TextFlow` are very large, processing all the `Text` nodes on each `hitTest` method invocation might cause performance issue. Hence implemented first approach. Added system test to validate the fix. ------------- Commit messages: - Fix insertion index calculation issue in TextFlow Changes: https://git.openjdk.org/jfx/pull/1091/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1091&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8304831 Stats: 182 lines in 2 files changed: 181 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1091.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1091/head:pull/1091 PR: https://git.openjdk.org/jfx/pull/1091 From john.hendrikx at gmail.com Fri Apr 14 07:57:29 2023 From: john.hendrikx at gmail.com (John Hendrikx) Date: Fri, 14 Apr 2023 09:57:29 +0200 Subject: Content Graph In-Reply-To: References: Message-ID: <52911245-a1f4-1daf-392e-7d51ab44d152@gmail.com> Some comments are inline. I think this may be a good idea, but I would like to know more about the use cases. All I can think of is that it *may* be useful when you want to persist a Scene (or the states involved); but as you're building the Scene yourself, you should already be aware of how it is structured.? I also saw the split pane use case, and I wonder if that can't be solved differently (perhaps SplitPane needs to be smarter here). As I barely know of any use cases for the current `lookup` methods, another set of them doesn't sound that useful to me either.? The only way I've ever used lookup (which is limited in how useful it is as it can't return an instance of a specific type) is to mark a node for ".initial-focus" when displaying a window. Some further questions as well: 1) Could Skins be inflated more eagerly? It wouldn't solve everything, but it would solve the SplitPane use case. 2) How far does a content graph go? It contains MenuItem. Should or will it contain ListView items? 3) Will this require a new observable list for every parent node, or is it going to be the same list for most of the nodes? On 13/04/2023 20:55, Michael Strau? wrote: > I've previously proposed an enhancement to introduce a "document > graph" to JavaFX that would solve a problem that many people have > encountered over the years: > https://mail.openjdk.org/pipermail/openjfx-dev/2022-June/034417.html > > In a nutshell, the problem is that the JavaFX scene graph is a black > box in the presence of control skins, which makes it hard to reason > about its structure. On top of that, several nodes that look like they > are part of the scene graph (MenuItem or Tab) aren't scene graph nodes > at all. > > > 1) Content Graph > > We can solve this problem by adding a content graph. The content graph > is a structure that comprises all content nodes of a scene. Content > nodes represent the significant scene content, which exludes all nodes > contributed by skins, but includes some of the aforementioned nodes > that are not part of the scene graph. > > The content graph consists of two new interfaces that live in the > `javafx.content` package: > > public interface ContentNode { > ContentParent getContentParent(); > > Styleable lookupContent(String selector); > Set lookupAllContent(String selector); > } > > public interface ContentParent extends ContentNode { > ObservableList getContentChildren(); > } Would the returned list here be read only? > These interfaces are implemented by `javafx.scene.Node` and > `javafx.scene.Parent`, but also by other classes like `MenuItem` or > `Tab`. Using these interfaces, the content graph can be traversed in > the same way as the scene graph. > > Consider the following program, which creates a simple user interface: > > var root = new VBox(); > var menuBtn = new MenuButton(); > menuBtn.getItems().add(new MenuItem("Item 1")); > menuBtn.getItems().add(new MenuItem("Item 2", new Rectangle())); > root.getChildren().add(menuBtn); > root.getChildren().add(new Button("Button 1", new Rectangle())); > root.getChildren().add(new Button("Button 2", new Circle())); > > Suppose a method `printSceneGraph(Node root)`, which traverses the > scene graph and prints out the nodes it encounters. > Here is the output before the UI is shown: > > javafx.scene.layout.VBox > ....javafx.scene.control.MenuButton > ....javafx.scene.control.Button > ....javafx.scene.control.Button > > And here's the output of the same method, but after the UI is shown: > > javafx.scene.layout.VBox > ....javafx.scene.control.MenuButton > ........javafx.scene.control.skin.MenuButtonSkinBase$MenuLabeledImpl > ............com.sun.javafx.scene.control.LabeledText > ........javafx.scene.layout.StackPane > ............javafx.scene.layout.StackPane > ....javafx.scene.control.Button > ........javafx.scene.shape.Rectangle > ........com.sun.javafx.scene.control.LabeledText > ....javafx.scene.control.Button > ........javafx.scene.shape.Circle > ........com.sun.javafx.scene.control.LabeledText > > Note that the scene graph contains many more nodes after skins have > been inflated, but it still doesn't contain the `MenuItem` instances. > > Now also suppose a method `printContentGraph(ContentNode root)`, which > does the same as before, but works on the content graph. > This is the output of that method: > > javafx.scene.layout.VBox > ....javafx.scene.control.MenuButton > ........javafx.content.Text > ........javafx.scene.control.MenuItem > ............javafx.content.Text > ........javafx.scene.control.MenuItem > ............javafx.content.Text > ............javafx.scene.shape.Rectangle > ....javafx.scene.control.Button > ........javafx.content.Text > ........javafx.scene.shape.Rectangle > ....javafx.scene.control.Button > ........javafx.content.Text > ........javafx.scene.shape.Circle I see a "javafx.content.Text" here, is that intended to be a new type as well? > Note that the content graph is not affected by skins, and the output > is the same whether the method is called before or after skin > inflation. > > > 2) Defining the Content Model > > The content graph consists of the content model of all participating > controls. Implementors are responsible for defining the content model > of a control by overriding the protected `buildContentModel` method, > and adding the content that is significant for the control: > > public class SplitPane { > ... > @Override > protected void buildContentModel( > Consumer> contentModel) { > super.buildContentModel(contentModel); > contentModel.accept(getItems()); > } > ... > } > > If a control subclass wants to extend the content model of an existing > control, it simply overrides the `buildContentModel` method again as > shown above. The content model of a subclass can only be extended, it > can't be constrained. This is analogous to how a subclass of `Labeled` > can only add new properties, but not remove the existing > `Labeled.text` and `Labeled.graphic` properties. For a lot of controls I think the content nodes will be fixed (SplitPane, Label, Button), but for others like MenuButton or containers these need to be modified. Does it make sense to use a similar model here that is used for properties? Some controls would still need to be able to modify the list directly, in which case subclasses could go that route as well, circumventing these protections. If the primary content graph is always determined by the "base" control, and subclasses can only contribute additional nodes without being able to modify anything, would that make it impossible to create a new container type node (or perhaps we're already constrained here by having to subclass Parent) ? --John From jhendrikx at openjdk.org Fri Apr 14 08:29:49 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Fri, 14 Apr 2023 08:29:49 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible Message-ID: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> These changes use base classes for custom properties where possible for the `ExpressionHelper` logic (and in one case, all the bind logic as well) instead of duplicating these each time. As the base classes receive far more scrutiny, this should reduce bugs in these re-implementations. ------------- Commit messages: - Use base classes where possible Changes: https://git.openjdk.org/jfx/pull/1092/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1092&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8305885 Stats: 394 lines in 8 files changed: 73 ins; 253 del; 68 mod Patch: https://git.openjdk.org/jfx/pull/1092.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1092/head:pull/1092 PR: https://git.openjdk.org/jfx/pull/1092 From jhendrikx at openjdk.org Fri Apr 14 09:47:45 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Fri, 14 Apr 2023 09:47:45 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v2] In-Reply-To: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: > These changes use base classes for custom properties where possible for the `ExpressionHelper` logic (and in one case, all the bind logic as well) instead of duplicating these each time. As the base classes receive far more scrutiny, this should reduce bugs in these re-implementations. John Hendrikx has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: Use property base classes where possible ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1092/files - new: https://git.openjdk.org/jfx/pull/1092/files/506b86e9..eda5d621 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1092&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1092&range=00-01 Stats: 133 lines in 1 file changed: 71 ins; 27 del; 35 mod Patch: https://git.openjdk.org/jfx/pull/1092.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1092/head:pull/1092 PR: https://git.openjdk.org/jfx/pull/1092 From ambarish.rapte at oracle.com Fri Apr 14 12:51:47 2023 From: ambarish.rapte at oracle.com (Ambarish Rapte) Date: Fri, 14 Apr 2023 12:51:47 +0000 Subject: CFV: New OpenJFX Committer: Karthik P K In-Reply-To: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> References: <174a99c5-f8a8-33e9-54b9-1fae5e668695@oracle.com> Message-ID: Vote: YES ~Ambarish -------------- next part -------------- An HTML attachment was scrubbed... URL: From mhanl at openjdk.org Fri Apr 14 16:17:48 2023 From: mhanl at openjdk.org (Marius Hanl) Date: Fri, 14 Apr 2023 16:17:48 GMT Subject: RFR: 8223373: Remove IntelliJ IDEA specific files from the source code repository [v5] In-Reply-To: References: <3zCUdkkbxcB1NMO9-VFrOgALNGa4k2vC0yXoyqYSbyQ=.596e4f9c-9101-4548-9d7e-134f06d1770c@github.com> Message-ID: <0I3XY4IbGS1qi4H52ZP5fFhJ_5thQyrYVsgc9tmFVus=.3ac1bc99-1782-46fd-98a5-30c0f847b1a1@github.com> On Fri, 7 Apr 2023 22:39:52 GMT, Kevin Rushforth wrote: >> Thiago Milczarek Sayao has updated the pull request incrementally with two additional commits since the last revision: >> >> - Revert "Make intellij see :systemTests dependecies" >> >> This reverts commit dca7eab24958e1214147b7d291f0faf52ea27ddf. >> - Make intellij see :systemTests dependecies > > .gitignore line 57: > >> 55: >> 56: # IntelliJ >> 57: out/ > > This would pick up more than just IntelliJ files. Are they all needed? `out` is the default `Compiler output` path in IntelliJ. But I don't think it is really needed here. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1009#discussion_r1167036713 From mariushanl at web.de Fri Apr 14 16:25:42 2023 From: mariushanl at web.de (Marius Hanl) Date: Fri, 14 Apr 2023 18:25:42 +0200 Subject: Aw: Re: Promote addEventHandler/removeEventHandler to EventTarget interface In-Reply-To: References: Message-ID: An HTML attachment was scrubbed... URL: From kevin.rushforth at oracle.com Fri Apr 14 17:32:28 2023 From: kevin.rushforth at oracle.com (Kevin Rushforth) Date: Fri, 14 Apr 2023 10:32:28 -0700 Subject: Promote addEventHandler/removeEventHandler to EventTarget interface In-Reply-To: References: Message-ID: <68e4df70-1419-cf7e-d559-f2714f6b5f96@oracle.com> I also think this would be a good change, after a little more looking at the compatibility impacts. Given that it is binary compatible (we need to verify that with some testing), and that the source incompatibility is limited to overriding classes of the four identified classes, which looks to be easy to resolve if an application runs into it, we should consider doing this. There are two cases to consider: 1) the case of an application or custom control that overrides Menu, MenuItem, TreeColumnBase and TreeItem; 2) the case of an application that implements EventTarget in an application class, and adds their own addEventTarget method with a different signature (basically an app that copies the pattern of the 4 above mentioned classes). Intuitively, I agree with Andy and Michael that the impact seems limited, but it would be helpful to survey applications, at least for those who are on this list, to get more feedback. -- Kevin On 4/13/2023 12:44 PM, Andy Goryachev wrote: > > I think this is a good idea, look what I had to do: > > https://github.com/openjdk/jfx/blob/f28896aa63592a37e7f78263548f3b2d4f2bc381/modules/javafx.controls/src/main/java/com/sun/javafx/scene/control/ListenerHelper.java#L396 > > I do agree with Kevin that we should look closely at any possible > compatibility issues.? I suspect the impact might be minimal due to > the fact that it's highly unlikely for anyone to extend the > EventTarget interface, but I could be wrong. > > -andy > > *From: *openjfx-dev on behalf of > Michael Strau? > *Date: *Wednesday, April 12, 2023 at 12:05 > *To: *Kevin Rushforth > *Cc: *openjfx-dev at openjdk.org > *Subject: *Re: Promote addEventHandler/removeEventHandler to > EventTarget interface > > I've created a draft PR with the proposed changes: > https://github.com/openjdk/jfx/pull/1090 > > Adding event handler management methods to `EventTarget` greatly > increases the usefulness of the event system for the reasons John and > I mentioned earlier. > I want to circle back to the compatibility issues that arise from the > proposed change: > > In general, adding a default-implemented method to an existing > interface is not in itself an incompatible change. However, > compatibility issues can arise when the new interface method doesn't > override, but clash with the erasure of a preexisting method on an > implementation of that interface. > This is exactly the issue we are facing, but the circumstances in > which this matters are extremely limited: > > The affected classes are Menu, MenuItem, TreeColumnBase and TreeItem. > > All of these classes provide a version of `addEventHandler` and > `removeEventHandler`, but in contast to all other implementations, the > signature of the method is slightly different. > While the usual signature is the following: > ??? void addEventHandler(EventType, EventHandler), > the mentioned classes instead declare a method with this signature: > ??? void addEventHandler(EventType, EventHandler). > > Note that the event handler is parameterized as , not . > This is most likely an oversight, since there doesn't seem to be a > justification to restrict event handlers to exactly T. > > Changing the method signature to conform to the correct version super T> is a binary-compatible change, since the erasure of both > methods remains the same. > However, it is not a source-compatible change. But the ways in which > this source incompatibility manifests are very limited: > > Callers of the modified API are not affected, since T <= ? super T. > This probably accounts for the vast majority of cases. > Overriding implementations will fail to compile without changing the > method signature. > > To summarize, here are the two cases where the proposed changes cause > compatibility issuse: > > 1. Existing `EventTarget` implementations that add a non-overriding, > but erasure-equal `addEventHandler` method. > 2. Subclasses of Menu, MenuItem, TreeColumnBase, or TreeItem that > override the `addEventHandler` method. > > The first case is the kind of risk that always comes with new > default-implemented interface methods. In this case, I think this is > where most of real-world compatibility problems could arise. > The second case doesn't seem relevant to me, because I don't see a > good reason why a subclass of Menu, MenuItem, TreeColumnBase, or > TreeView would override the `addEventHandler`, ... methods. > > In the end, as with all additions to existing interfaces, we need to > carefully consider the benefits of the enhancement against potential > risks. > In this case, I think the risks are quite low, while the benefits are > very significant. > > > On Tue, Mar 7, 2023 at 3:35?PM Kevin Rushforth > wrote: > > > > An incompatible change in a fundamental interface such as EventTarget is > > not something we would want to do, so any proposed changes will need to > > retain compatibility (both binary and source). At a minimum, this means > > that any newly added methods would need to have a default > > implementation, and we would need to look closely at other aspects of > > compatibility. > > > > -- Kevin > > > > > > On 3/7/2023 1:24 AM, John Hendrikx wrote: > > > Hi Michael, > > > > > > Did you file a JIRA issue for this one? > > > > > > I've recently also been doing some rewriting to use the Event system > > > more.? I'm removing custom Scene walking code (and looking at > > > Node.getProperties) to do "event handling", and I've now discovered > > > that it could be done quite a bit nicer by using the provided event > > > mechanism. > > > > > > I've encountered a few things that annoy me about the event system: > > > > > > 1) I'm making use of Presentation classes (Models) that only associate > > > with things in javafx.base (Event, EventTarget, Properties). These > > > presentations need to register event handlers at some point, but this > > > can only be done on Nodes; having this logic close to the Presentation > > > code makes sense, but it would make them dependent on javafx.graphics; > > > if I could do this via EventTarget, the dependency would not be > needed. > > > > > > 2) When you fire an event (via Node.fireEvent for example), there is > > > no feedback you can obtain whether the event was consumed or not as > > > the final event is not returned to check `isConsumed` on (internal > > > calls do have this information, but it is not exposed at the last > step). > > > > > > 3) Related to 2), I think EventTarget could also have a method to > > > dispatch events (so you can dispatch an event easily to any target, > > > not just via the convenience method Node#fireEvent).? See this ticket: > > > https://bugs.openjdk.org/browse/JDK-8303209 > > > > > > Perhaps we can work together on this, or if you're not currently > > > working on it I could take a stab at solving all of these issues. > > > > > > --John > > > > > > On 17/03/2022 21:01, Michael Strau? wrote: > > >> I'm working on an application that uses the JavaFX event system > > >> extensively, and I'm finding it quite hard to use common code for > > >> event handler registrations. > > >> > > >> The problem is that the `EventTarget` interface contains no > > >> addEventHandler/removeEventHandler methods, and as a consequence of > > >> that, code that uses `EventTarget` ends up requiring lots of brittle > > >> instanceof tests to call these methods on all the different > > >> implementations of `EventTarget`. > > >> > > >> There are three buckets of `EventTarget` implementations: > > >> > > >> 1) Implementations that declare the following methods: > > >>????? void addEventHandler(EventType, > > >> EventHandler); > > >>????? void removeEventHandler(EventType, > > >> EventHandler); > > >>????? void addEventFilter(EventType, > EventHandler > >> super T>); > > >>????? void removeEventFilter(EventType, > > >> EventHandler); > > >> --> Node, Scene, Window, Transform, Task, Service > > >> > > >> 2) Implementations that declare the following methods: > > >>????? void addEventHandler(EventType, > > >> EventHandler); > > >>????? void removeEventHandler(EventType, > > >> EventHandler); > > >> --> MenuItem, TreeItem, TableColumnBase > > >> > > >> (Note that the EventHandler argument ist parameterized as > > >> EventHandler, not EventHandler as in the first set of > > >> methods.) > > >> > > >> 3) Implementations that don't declare any methods to add or remove > > >> event handlers: > > >> --> Dialog, Tab > > >> > > >> > > >> I think the situation can be improved by promoting the bucket 1 > > >> methods to the `EventTarget` interface, so they can be used > > >> consistently across all implementations of `EventTarget`. > > >> > > >> This works seamlessly for bucket 1 and bucket 3 implementations. > > >> > > >> With bucket 2, there's the problem that, inconsistently, the > > >> EventHandler argument is not a lower-bounded wildcard. > > >> Unfortunately, a method with an EventHandler parameter cannot > > >> implement an interface method that expects EventHandler. > > >> > > >> However, since the erasure of the method remains the same, changing > > >> the method signature would technically be a binary-compatible change. > > >> > > >> Do you think this is a useful improvement? > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From duke at openjdk.org Fri Apr 14 22:48:47 2023 From: duke at openjdk.org (Martin Fox) Date: Fri, 14 Apr 2023 22:48:47 GMT Subject: RFR: 8278924: [Linux] Robot key test can fail if multiple keyboard layouts are installed [v2] In-Reply-To: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> References: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> Message-ID: > The Robot implementation on Linux did not consult the current layout when mapping from a KeyCode to a hardware code. Internally it retrieved results for all the layouts but just picked the first one it saw leading to random effects. Though not part of the original bug report, the code also ignored the shift level when choosing which result to pick. On a French layout the dollar sign is on two keys (AltGr 4 is the second one) and the code could choose either one. Same is true for pound. > > This PR consults the current layout and only on shift level 0 which is the same level used in get_glass_key to figure out which KeyCode to assign when generating a KeyEvent. Martin Fox has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains two additional commits since the last revision: - Merge remote-tracking branch 'upstream/master' into linuxrobot - Robot no longer gets confused by multiple layouts ------------- Changes: - all: https://git.openjdk.org/jfx/pull/718/files - new: https://git.openjdk.org/jfx/pull/718/files/ad88f044..51fcd047 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=718&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=718&range=00-01 Stats: 1319402 lines in 14954 files changed: 713165 ins; 422282 del; 183955 mod Patch: https://git.openjdk.org/jfx/pull/718.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/718/head:pull/718 PR: https://git.openjdk.org/jfx/pull/718 From kcr at openjdk.org Sat Apr 15 00:06:43 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 15 Apr 2023 00:06:43 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v2] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: On Fri, 14 Apr 2023 09:47:45 GMT, John Hendrikx wrote: >> These changes use base classes for custom properties where possible for the `ExpressionHelper` logic instead of duplicating these each time. > > John Hendrikx has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: > > Use property base classes where possible Looks like a fairly straight-forward change. Are there any memory implications? I wouldn't think so, but it's worth checking. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1092#issuecomment-1509408274 From jhendrikx at openjdk.org Sat Apr 15 00:52:42 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 15 Apr 2023 00:52:42 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v2] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: <9f92rXXEd8aLBhZK1mE12PPMvk6mm0l_i-2cabd7YrA=.532304ab-0742-4eec-a5a3-baf6970a4904@github.com> On Sat, 15 Apr 2023 00:04:03 GMT, Kevin Rushforth wrote: >> John Hendrikx has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: >> >> Use property base classes where possible > > Looks like a fairly straight-forward change. Are there any memory implications? I wouldn't think so, but it's worth checking. @kevinrushforth There aren't any memory implications, `ReadOnlyPropertyBase` does not add additional fields (beyond the `ExpressionHelper` field). ------------- PR Comment: https://git.openjdk.org/jfx/pull/1092#issuecomment-1509436007 From mstrauss at openjdk.org Sat Apr 15 01:28:43 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 15 Apr 2023 01:28:43 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v2] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: On Fri, 14 Apr 2023 09:47:45 GMT, John Hendrikx wrote: >> These changes use base classes for custom properties where possible for the `ExpressionHelper` logic instead of duplicating these each time. > > John Hendrikx has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: > > Use property base classes where possible Looks good to me. modules/javafx.graphics/src/main/java/com/sun/javafx/scene/TreeShowingExpression.java line 44: > 42: * an observable form. > 43: */ > 44: public class TreeShowingExpression extends ReadOnlyBooleanPropertyBase { Maybe you could rename the class to `TreeShowingProperty`? ------------- PR Review: https://git.openjdk.org/jfx/pull/1092#pullrequestreview-1386286257 PR Review Comment: https://git.openjdk.org/jfx/pull/1092#discussion_r1167353328 From jhendrikx at openjdk.org Sat Apr 15 01:39:39 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 15 Apr 2023 01:39:39 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v2] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: On Sat, 15 Apr 2023 01:26:13 GMT, Michael Strau? wrote: >> John Hendrikx has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: >> >> Use property base classes where possible > > modules/javafx.graphics/src/main/java/com/sun/javafx/scene/TreeShowingExpression.java line 44: > >> 42: * an observable form. >> 43: */ >> 44: public class TreeShowingExpression extends ReadOnlyBooleanPropertyBase { > > Maybe you could rename the class to `TreeShowingProperty`? Yeah, that would definitely be better. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1092#discussion_r1167354675 From mstrauss at openjdk.org Sat Apr 15 04:55:39 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 15 Apr 2023 04:55:39 GMT Subject: RFR: 8306021: Add event handler management to EventTarget Message-ID: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> This PR adds the following methods to the `EventTarget` interface: 1. `addEventHandler` 2. `removeEventHandler` 3. `addEventFilter` 4. `removeEventFilter` ------------- Commit messages: - remove final modifier - remove final modifier - documentation changes - add final modifiers in Dialog class - revert some changes - doc changes - Promote addEventHandler/addEventFilter to EventTarget Changes: https://git.openjdk.org/jfx/pull/1090/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1090&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8306021 Stats: 584 lines in 13 files changed: 166 ins; 355 del; 63 mod Patch: https://git.openjdk.org/jfx/pull/1090.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1090/head:pull/1090 PR: https://git.openjdk.org/jfx/pull/1090 From kcr at openjdk.org Sat Apr 15 04:55:40 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 15 Apr 2023 04:55:40 GMT Subject: RFR: 8306021: Add event handler management to EventTarget In-Reply-To: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> Message-ID: On Wed, 12 Apr 2023 18:19:11 GMT, Michael Strau? wrote: > This PR adds the following methods to the `EventTarget` interface: > 1. `addEventHandler` > 2. `removeEventHandler` > 3. `addEventFilter` > 4. `removeEventFilter` If we proceed with this, we will need a CSR that documents the incompatibilities that are mentioned in the thread on openjfx-dev. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1090#issuecomment-1509405226 From mstrauss at openjdk.org Sat Apr 15 04:55:41 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 15 Apr 2023 04:55:41 GMT Subject: RFR: 8306021: Add event handler management to EventTarget In-Reply-To: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> Message-ID: On Wed, 12 Apr 2023 18:19:11 GMT, Michael Strau? wrote: > This PR adds the following methods to the `EventTarget` interface: > 1. `addEventHandler` > 2. `removeEventHandler` > 3. `addEventFilter` > 4. `removeEventFilter` This PR assumes that changing the first method signature to the second is a binary-compatible change: 1. void addEventHandler(EventType, EventHandler) 2. void addEventHandler(EventType, EventHandler) To verify this, I've created the following test: import java.util.function.Consumer; // Test.java public class Test { public static void test(Consumer c) { System.out.println("it works"); } } // Main.java public class Main { public static void main(String[] args) { Consumer c = param -> {}; Test.test(c); } } Note that `Consumer`, like `EventHandler`, only uses the generic type parameter as an _input_ argument. After compiling both files, I changed the signature of the `test` method to `void test(Consumer)`. Then I made sure to _only_ recompile the `Test.java` file and ran the `Main` program, which succeeded. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1090#issuecomment-1509495524 From jhendrikx at openjdk.org Sat Apr 15 09:44:41 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 15 Apr 2023 09:44:41 GMT Subject: RFR: 8306021: Add event handler management to EventTarget In-Reply-To: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> Message-ID: On Wed, 12 Apr 2023 18:19:11 GMT, Michael Strau? wrote: > This PR adds the following methods to the `EventTarget` interface: > 1. `addEventHandler` > 2. `removeEventHandler` > 3. `addEventFilter` > 4. `removeEventFilter` I checked everything, and didn't see any problems; looks good! ------------- Marked as reviewed by jhendrikx (Committer). PR Review: https://git.openjdk.org/jfx/pull/1090#pullrequestreview-1386424714 From kcr at openjdk.org Sat Apr 15 13:08:41 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 15 Apr 2023 13:08:41 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v2] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: On Fri, 14 Apr 2023 09:47:45 GMT, John Hendrikx wrote: >> These changes use base classes for custom properties where possible for the `ExpressionHelper` logic instead of duplicating these each time. > > John Hendrikx has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: > > Use property base classes where possible Reviewers: @arapte ------------- PR Comment: https://git.openjdk.org/jfx/pull/1092#issuecomment-1509816969 From kcr at openjdk.org Sat Apr 15 13:08:43 2023 From: kcr at openjdk.org (Kevin Rushforth) Date: Sat, 15 Apr 2023 13:08:43 GMT Subject: RFR: 8304831: TextFlow.hitTest.insertionIndex incorrect with surrogate pairs In-Reply-To: <3SN8lehcrLh8DJJ_qumZ_eGYw8y5aglKYVY9PPNquk0=.166e3e46-58c3-4fcf-b032-39f9fb9dd59b@github.com> References: <3SN8lehcrLh8DJJ_qumZ_eGYw8y5aglKYVY9PPNquk0=.166e3e46-58c3-4fcf-b032-39f9fb9dd59b@github.com> Message-ID: On Fri, 14 Apr 2023 07:35:33 GMT, Karthik P K wrote: > Since surrogate pairs are internally considered as 2 characters and text field is null in `HitInfo` when `getInsertionIndex` is invoked from `TextFlow`, wrong insertion index was returned. > > Updated code to calculate insertion index in `getHitInfo` method of `PrismTextLayout` class when `hitTest` of trailing side of surrogate pair is requested. Since text runs are processed in this method already, calculating the insertion index in this method looks better than calculating in `getInsertionIndex` of `HitInfo` method. > The latter approach also requires the text to be sent to `HitInfo` as parameter from the `hitTest` method of `TextFlow`. If the number of `Text` nodes in `TextFlow` are very large, processing all the `Text` nodes on each `hitTest` method invocation might cause performance issue. Hence implemented first approach. > > Added system test to validate the fix. Reviewers: @prrace @andy-goryachev-oracle ------------- PR Comment: https://git.openjdk.org/jfx/pull/1091#issuecomment-1509816515 From mstrauss at openjdk.org Sat Apr 15 18:01:28 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 15 Apr 2023 18:01:28 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v2] In-Reply-To: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> Message-ID: <0ZqMcHZ78UF04XZFUQ6H1yv016hFX_E9XvThZtAIwB8=.5822a500-5872-46a9-a315-8a4a509a91c7@github.com> > This PR adds the following methods to the `EventTarget` interface: > 1. `addEventHandler` > 2. `removeEventHandler` > 3. `addEventFilter` > 4. `removeEventFilter` Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: revert a change in Menu ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1090/files - new: https://git.openjdk.org/jfx/pull/1090/files/d395d084..7db7f79a Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1090&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1090&range=00-01 Stats: 6 lines in 1 file changed: 6 ins; 0 del; 0 mod Patch: https://git.openjdk.org/jfx/pull/1090.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1090/head:pull/1090 PR: https://git.openjdk.org/jfx/pull/1090 From mstrauss at openjdk.org Sat Apr 15 18:32:38 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sat, 15 Apr 2023 18:32:38 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v2] In-Reply-To: <0ZqMcHZ78UF04XZFUQ6H1yv016hFX_E9XvThZtAIwB8=.5822a500-5872-46a9-a315-8a4a509a91c7@github.com> References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> <0ZqMcHZ78UF04XZFUQ6H1yv016hFX_E9XvThZtAIwB8=.5822a500-5872-46a9-a315-8a4a509a91c7@github.com> Message-ID: On Sat, 15 Apr 2023 18:01:28 GMT, Michael Strau? wrote: >> This PR adds the following methods to the `EventTarget` interface: >> 1. `addEventHandler` >> 2. `removeEventHandler` >> 3. `addEventFilter` >> 4. `removeEventFilter` > > Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: > > revert a change in Menu I've reverted a change that caused a unit test failure. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1090#issuecomment-1509922579 From jhendrikx at openjdk.org Sat Apr 15 19:33:52 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 15 Apr 2023 19:33:52 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs Message-ID: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> This provides and uses a new implementation of `ExpressionHelper`, called `ListenerManager` with improved semantics. # Behavior |Listener...|ExpressionHelper|ListenerManager| |---|---|---| |Invocation Order|In order they were registered, invalidation listeners always before change listeners|(unchanged)| |Removal during Notification|All listeners present when notification started are notified, but excluded for any nested changes|Listeners are removed immediately regardless of nesting| |Addition during Notification|Only listeners present when notification started are notified, but included for any nested changes|New listeners are never called during the current notification regardless of nesting| ## Nested notifications: | |ExpressionHelper|ListenerManager| |---|---|---| |Type|Depth first (call stack increases for each nested level)|(same)| |# of Calls|Listeners * Depth (using incorrect old values)|Collapses nested changes, skipping non-changes| |Vetoing Possible?|No|Yes| |Old Value correctness|Only for listeners called before listeners making nested changes|Always| # Performance |Listener|ExpressionHelper|ListenerManager| |---|---|---| |Addition|Array based, append in empty slot, resize as needed|(same)| |Removal|Array based, shift array, resize as needed|(same)| |Addition during notification|Array is copied, removing collected WeakListeneres in the process|Tracked (append at end)| |Removal during notification|As above|Entry is `null`ed| |Notification completion with changes|-|Null entries (and collected WeakListeners) are removed| |Notifying Invalidation Listeners|1 ns each|(same)| |Notifying Change Listeners|1 ns each (*)|2-3 ns each| (*) a simple for loop is close to optimal, but unfortunately does not provide correct old values # Memory Use Does not include alignment, and assumes a 32-bit VM or one that is using compressed oops. |Listener|ExpressionHelper|ListenerManager|OldValueCaching ListenerManager| |---|---|---|---| |No Listeners|none|none|none| |Single InvalidationListener|16 bytes overhead|none|none| |Single ChangeListener|20 bytes overhead|none|16 bytes overhead| |Multiple listeners|57 + 4 per listener (excluding unused slots)|57 + 4 per listener (excluding unused slots)|61 + 4 per listener (excluding unused slots)| # About nested changes Nested changes are simply changes that are made to a property that is currently in the process of notifying its listeners. This all occurs on the same thread, and a nested change is nothing more than the same property being modified, triggering its listeners again deeper in the call stack with another notification, while higher up the call stack a notification is still being handled: (top of stack) fireValueChangedEvent (property A) <-- nested notification setValue (property A) <-- listener modifies property A changed (Listener 1) <-- a listener called by original notification fireValueChangedEvent (property A) <-- original notification ## How do nested changes look? Let's say we have three listeners, where the middle listener changes values to uppercase. When changing a property with the initial value "A" to a lowercase "b" the listeners would see the following events: ### ExpressionHelper |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| |---|---|---|---|---|---| | 0 |T1 |A -> b| | | | | 0 |T2 | |A -> b| |Value is changed to B| | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | | 1 |T4 | |b -> B| | | | 1 |T5 | | |b -> B| | | 0 |T6 | | |A -> B|Top level loop is resumed| Note how the values received by the 3rd listener are non-sensical. It receives two changes both of which changes to B from old values that are out of order. ### ListenerManager (new) This how ListenerManager sends out these events: |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| |---|---|---|---|---|---| | 0 |T1 |A -> b| | | | | 0 |T2 | |A -> b| |Value is changed to B| | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | | 1 |T4 | |b -> B| | The nested loop is terminated early at this point | | 0 |T5 | | |A -> B|Top level loop is resumed| Note how the 3rd listener now receives an event that reflects what actually happened from its perspective. Also note that less events overall needed to be send out. # About Invocation Order A lot of code depends on the fact that an earlier registered listener of the same type is called **before** a later registered later of the same type. For listeners of different types it is a bit less clear. What is clear however is that invalidation and change listeners are defined by separate interfaces. Mixing their invocations (to conserve registration order) would not make sense. Historically, invalidation listeners are called before change listeners. No doubt, code will be (unknowingly) relying on this in today's JavaFX applications so changing this is not recommended. Perhaps there is reason to say that invalidation listeners should be called first as they're defined by the super interface of `ObservableValue` which introduces change listeners. # About Listener Add/Remove performance Many discussions have happened in the past to improve the performance of removing listeners, ranging from using maps to ordered data structures with better remove performance. Often these solutions would subtly change the notification order, or increase the overhead per listener significantly. But these discussions never really looked at the other consequences of having tens of thousands of listeners. Even if listeners could be removed in something approaching O(1) time (additions are already O(1) and so are not the issue), what about the performance of notifying that many listeners? That will still be O(n), and so even if JavaFX could handle addition and removal of that many listeners comfortably, actually using a property with that many listeners is still impossible as it would block the FX thread for far too long when sending out that many notifications. Therefore, I'm of the opinion that "fixing" this "problem" is pointless. Instead, having that many listeners should be considered a design flaw in the application. A solution that registers only a single listener that updates a shared model may be much more appropriate. # About Old Value Correctness ...and why it is important. A change listener provides a callback that gives the old and the new value. One may reasonably expect that these values are never the same, and one may reasonably expect that the given old value is the same as the previous invocation's new value (if there was a previous invocation). In JavaFX, many change listeners are used for important tasks, ranging from reverting changes in order to veto something, to registering and unregistering listeners on properties. Many of those change listeners do not care about the old value, but there are a significant number that use it and rely on it being correct. A common example is the registering of a listener on the "new" value, and removing the same listener from the "old" value in order to maintain a link to some other property that changes location: (obs, old, current) -> { if (old != null) { old.removeListener(x); } if (current != null) { current.addListener(x); } } The above code looks bug free, and it would be if the provided old values are always correct. Unfortunately, this does not have to be the case. When a nested change is made (which can be made by a user registered listener on the same property), `ExpressionHelper` makes no effort to ensure that for all registered listener the received old and new values make sense. This leads to listeners being notified twice with the same "new" value for example, but with a different old value. Imagine the above listener receives the following change events: scene1 becomes scene3 scene2 becomes scene3 The above code would remove its listeners from `scene1` and `scene2`, and register two listeners on `scene3`. This leads to the listener being called twice when something changes. When later the scene changes to `scene4`, it receives: scene3 becomes scene4 Because it registered its listener twice on `scene3`, and only removes one of them, it now has listeners on both `scene3` and `scene4`. Clearly it is incredibly important that changes make sense, or even simple code that looks innocuous becomes problematic. # The PR The `ListenerManager` differs from `ExpressionHelper` in the following ways: - Provides correct old/new values to `ChangeListener`s under all circumstances - Unnecessary change events are never sent - Single invalidation or change listeners are inlined directly into the observable class (in other words, properties with only a single listener don't take up any extra space at all) - Performance is slightly worse when calling **change** listeners (but remember that `ExpressionHelper` is not following the contract). - Removed listeners are never called after being removed (even if they were part of the initial list when the notification triggered) - Added listeners are only called when a new non-nested (top level) notification starts - Locking and maintaining the listener list works a bit differently -- the main takeaway is that the list indices remain the same when modified during nested modifications, which allows using the same list no matter how deep the nesting - No reference is stored to the ObservableValue and no copy is kept of the current value - Memory use when there is more than 1 listener should be similar, and better when not - Although complicated, the code is I think much better separated, and more focused on accomplishing a single task: - `ListenerManager` manages the listener storage in property classes, and the transformation between the listener variants (it either uses listeners directly, or uses a `ListenerList` when there are multiple listeners). - `ListenerListBase` handles the locking and compacting of its listener lists. - `ListenerList` which extends `ListenerListBase` is only concerned with the recursion algorithm for notification. - `ArrayManager` handles resizing and reallocating of arrays. - There are variants of `ListenerList` and `ListenerManager` which can cache their old values when its not possible to supply these (this has a cost, and is what `ExpressionHelper` does by default). The notification mechanism deals with nested notifications by tracking how many listeners were notified already before the nested notification occurs. For example, if 5 listeners were notified, and then listener 5 makes a nested change, then in that nested changed only the first 5 listeners are notified again (if they still exist). When the top level resumes, it continues where it left of and notifies listeners 6 and so on. This ensures that all notifications are always correct, and that listeners that "veto" changes can effectively block later listeners from seeing those at all. For example, if the first listener always uppercases any received values, then any succeeding listeners will always see only uppercase values. The first listener receives two notifications (`X -> a` and `a -> A`), and the second receives only `X -> A`. Contrast this with the old `ExpressionHelper`, which sends odd notifications to the second listener (`a -> A` and `X -> A`, in that order). Unfortunately, due to a somewhat weird design choice in the PropertyBase classes, the strategy of not having to cache the "current value" (or old value) can't be used (it can only be used for Bindings for now). So there is another variant of this helper, called `OldValueCachingListenerHelper`, with some slight differences: - Has an extra field for storing the old value when there are any `ChangeListener`s active - Can't store a `ChangeListener` inline; a minimal wrapper is needed to track the old value (ExpressionHelper does the same) ------------- Commit messages: - Add comment - Add JUnit tests for the ListenerList variants - Fix warnings and docs - Clean ups and speed improvements - Small doc adjustment - Use listener manager for the read only properties - Extra test cases for coverage - Big clean-up - ArrayManager improvements and tests - Improve tests - ... and 3 more: https://git.openjdk.org/jfx/compare/102a90ce...351520f0 Changes: https://git.openjdk.org/jfx/pull/1081/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=00 Issue: https://bugs.openjdk.org/browse/JDK-8290310 Stats: 4233 lines in 39 files changed: 4073 ins; 5 del; 155 mod Patch: https://git.openjdk.org/jfx/pull/1081.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1081/head:pull/1081 PR: https://git.openjdk.org/jfx/pull/1081 From nlisker at openjdk.org Sat Apr 15 19:33:52 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Sat, 15 Apr 2023 19:33:52 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs In-Reply-To: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: On Tue, 4 Apr 2023 15:22:48 GMT, John Hendrikx wrote: > This provides and uses a new implementation of `ExpressionHelper`, called `ListenerManager` with improved semantics. > > # Behavior > > |Listener...|ExpressionHelper|ListenerManager| > |---|---|---| > |Invocation Order|In order they were registered, invalidation listeners always before change listeners|(unchanged)| > |Removal during Notification|All listeners present when notification started are notified, but excluded for any nested changes|Listeners are removed immediately regardless of nesting| > |Addition during Notification|Only listeners present when notification started are notified, but included for any nested changes|New listeners are never called during the current notification regardless of nesting| > > ## Nested notifications: > > | |ExpressionHelper|ListenerManager| > |---|---|---| > |Type|Depth first (call stack increases for each nested level)|(same)| > |# of Calls|Listeners * Depth (using incorrect old values)|Collapses nested changes, skipping non-changes| > |Vetoing Possible?|No|Yes| > |Old Value correctness|Only for listeners called before listeners making nested changes|Always| > > # Performance > > |Listener|ExpressionHelper|ListenerManager| > |---|---|---| > |Addition|Array based, append in empty slot, resize as needed|(same)| > |Removal|Array based, shift array, resize as needed|(same)| > |Addition during notification|Array is copied, removing collected WeakListeneres in the process|Tracked (append at end)| > |Removal during notification|As above|Entry is `null`ed| > |Notification completion with changes|-|Null entries (and collected WeakListeners) are removed| > |Notifying Invalidation Listeners|1 ns each|(same)| > |Notifying Change Listeners|1 ns each (*)|2-3 ns each| > > (*) a simple for loop is close to optimal, but unfortunately does not provide correct old values > > # Memory Use > > Does not include alignment, and assumes a 32-bit VM or one that is using compressed oops. > > |Listener|ExpressionHelper|ListenerManager|OldValueCaching ListenerManager| > |---|---|---|---| > |No Listeners|none|none|none| > |Single InvalidationListener|16 bytes overhead|none|none| > |Single ChangeListener|20 bytes overhead|none|16 bytes overhead| > |Multiple listeners|57 + 4 per listener (excluding unused slots)|57 + 4 per listener (excluding unused slots)|61 + 4 per listener (excluding unused slots)| > > # About nested changes > > Nested changes are simply changes that are made to a property that is currently in the process of notifying its listeners. This all occurs on the same thread, and a nested change is nothing more than the same property being modified, triggering its listeners again deeper in the call stack with another notification, while higher up the call stack a notification is still being handled: > > (top of stack) > fireValueChangedEvent (property A) <-- nested notification > setValue (property A) <-- listener modifies property A > changed (Listener 1) <-- a listener called by original notification > fireValueChangedEvent (property A) <-- original notification > > ## How do nested changes look? > > Let's say we have three listeners, where the middle listener changes values to uppercase. When changing a property with the initial value "A" to a lowercase "b" the listeners would see the following events: > > ### ExpressionHelper > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | | > | 1 |T5 | | |b -> B| | > | 0 |T6 | | |A -> B|Top level loop is resumed| > > Note how the values received by the 3rd listener are non-sensical. It receives two changes both of which changes to B from old values that are out of order. > > ### ListenerManager (new) > This how ListenerManager sends out these events: > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | The nested loop is terminated early at this point | > | 0 |T5 | | |A -> B|Top level loop is resumed| > > Note how the 3rd listener now receives an event that reflects what actually happened from its perspective. Also note that less events overall needed to be send out. > > # About Invocation Order > > A lot of code depends on the fact that an earlier registered listener of the same type is called **before** a later registered later of the same type. For listeners of different types it is a bit less clear. What is clear however is that invalidation and change listeners are defined by separate interfaces. Mixing their invocations (to conserve registration order) would not make sense. Historically, invalidation listeners are called before change listeners. No doubt, code will be (unknowingly) relying on this in today's JavaFX applications so changing this is not recommended. Perhaps there is reason to say that invalidation listeners should be called first as they're defined by the super interface of `ObservableValue` which introduces change listeners. > > # About Listener Add/Remove performance > > Many discussions have happened in the past to improve the performance of removing listeners, ranging from using maps to ordered data structures with better remove performance. Often these solutions would subtly change the notification order, or increase the overhead per listener significantly. > > But these discussions never really looked at the other consequences of having tens of thousands of listeners. Even if listeners could be removed in something approaching O(1) time (additions are already O(1) and so are not the issue), what about the performance of notifying that many listeners? That will still be O(n), and so even if JavaFX could handle addition and removal of that many listeners comfortably, actually using a property with that many listeners is still impossible as it would block the FX thread for far too long when sending out that many notifications. > > Therefore, I'm of the opinion that "fixing" this "problem" is pointless. Instead, having that many listeners should be considered a design flaw in the application. A solution that registers only a single listener that updates a shared model may be much more appropriate. > > # About Old Value Correctness > ...and why it is important. > > A change listener provides a callback that gives the old and the new value. One may reasonably expect that these values are never the same, and one may reasonably expect that the given old value is the same as the previous invocation's new value (if there was a previous invocation). > > In JavaFX, many change listeners are used for important tasks, ranging from reverting changes in order to veto something, to registering and unregistering listeners on properties. Many of those change listeners do not care about the old value, but there are a significant number that use it and rely on it being correct. A common example is the registering of a listener on the "new" value, and removing the same listener from the "old" value in order to maintain a link to some other property that changes location: > > (obs, old, current) -> { > if (old != null) { > old.removeListener(x); > } > if (current != null) { > current.addListener(x); > } > } > > The above code looks bug free, and it would be if the provided old values are always correct. Unfortunately, this does not have to be the case. When a nested change is made (which can be made by a user registered listener on the same property), `ExpressionHelper` makes no effort to ensure that for all registered listener the received old and new values make sense. This leads to listeners being notified twice with the same "new" value for example, but with a different old value. Imagine the above listener receives the following change events: > > scene1 becomes scene3 > scene2 becomes scene3 > > The above code would remove its listeners from `scene1` and `scene2`, and register two listeners on `scene3`. This leads to the listener being called twice when something changes. When later the scene changes to `scene4`, it receives: > > scene3 becomes scene4 > > Because it registered its listener twice on `scene3`, and only removes one of them, it now has listeners on both `scene3` and `scene4`. > > Clearly it is incredibly important that changes make sense, or even simple code that looks innocuous becomes problematic. > > # The PR > > The `ListenerManager` differs from `ExpressionHelper` in the following ways: > - Provides correct old/new values to `ChangeListener`s under all circumstances > - Unnecessary change events are never sent > - Single invalidation or change listeners are inlined directly into the observable class (in other words, properties with only a single listener don't take up any extra space at all) > - Performance is slightly worse when calling **change** listeners (but remember that `ExpressionHelper` is not following the contract). > - Removed listeners are never called after being removed (even if they were part of the initial list when the notification triggered) > - Added listeners are only called when a new non-nested (top level) notification starts > - Locking and maintaining the listener list works a bit differently -- the main takeaway is that the list indices remain the same when modified during nested modifications, which allows using the same list no matter how deep the nesting > - No reference is stored to the ObservableValue and no copy is kept of the current value > - Memory use when there is more than 1 listener should be similar, and better when not > - Although complicated, the code is I think much better separated, and more focused on accomplishing a single task: > - `ListenerManager` manages the listener storage in property classes, and the transformation between the listener variants (it either uses listeners directly, or uses a `ListenerList` when there are multiple listeners). > - `ListenerListBase` handles the locking and compacting of its listener lists. > - `ListenerList` which extends `ListenerListBase` is only concerned with the recursion algorithm for notification. > - `ArrayManager` handles resizing and reallocating of arrays. > - There are variants of `ListenerList` and `ListenerManager` which can cache their old values when its not possible to supply these (this has a cost, and is what `ExpressionHelper` does by default). > > The notification mechanism deals with nested notifications by tracking how many listeners were notified already before the nested notification occurs. For example, if 5 listeners were notified, and then listener 5 makes a nested change, then in that nested changed only the first 5 listeners are notified again (if they still exist). When the top level resumes, it continues where it left of and notifies listeners 6 and so on. This ensures that all notifications are always correct, and that listeners that "veto" changes can effectively block later listeners from seeing those at all. > > For example, if the first listener always uppercases any received values, then any succeeding listeners will always see only uppercase values. The first listener receives two notifications (`X -> a` and `a -> A`), and the second receives only `X -> A`. Contrast this with the old `ExpressionHelper`, which sends odd notifications to the second listener (`a -> A` and `X -> A`, in that order). > > Unfortunately, due to a somewhat weird design choice in the PropertyBase classes, the strategy of not having to cache the "current value" (or old value) can't be used (it can only be used for Bindings for now). So there is another variant of this helper, called `OldValueCachingListenerHelper`, with some slight differences: > > - Has an extra field for storing the old value when there are any `ChangeListener`s active > - Can't store a `ChangeListener` inline; a minimal wrapper is needed to track the old value (ExpressionHelper does the same) John and I discussed this off-list. I will write a short review of this change. ### Behavior The solution implements has the following behaviors, which are compared to the current (partially-flawed) ones: * Listeners are invoked in the order they were registered, with invalidation listeners being invoked before change listeners. This is also the current behavior. The behavior of invoking all listeners according to the order of registrations will be investigated. * Listeners that are removed during event propagation will be removed immediately, and will not receive the event (if they hadn't already). This differs from the current behavior of removing the listeners only after the event finished (buggy implementation). * Listeners that are added during event propagation will be effectively added after the event finishes, and will not receive the event during which they were added. This is also the current behavior (buggy implementation). The behavior of adding the listeners immediately, as is done with removal, will be investigated. * Nested events are invoked "depth-first", meaning that the parent event propagation is halted until the nested event finishes (see below). This differs from the current behavior that takes the "breadth-first" approach - each event finishes before the nested one starts (buggy implementation). * Nested events are only handled by listeners who received the parent event already so that they can react to the new change. Listeners that did not receive the parent event will only get a single (updated) event so that they don't react to irrelevant values. This allows vetoing, This differs from the current behavior that sends all events to all listeners (buggy implementation). ### Examples Suppose 5 change listeners are registered when an event starts. **Removal during an event** L1 gets the event L2 gets the event and removes L4 L3 gets the event and removes L2 (L2 already got the event) L4 does not get the event (removed by L2) L5 gets the event final listeners: L1, L3, L5 **Addition during an event** L1 gets the event L2 gets the event and adds L6 L3-L5 get the event L6 does not get the event (added by L2) final listeners: L1 - L6 **Nested event** (value change during an event) The observable value changes from 0 to 1 L1 gets 0->1 L2 gets 0->1 L3 gets 0->1 and sets the value to 2 (vetoing) L1-L3 get 1->2 (nested event - listeners can react to the new change) L4-L5 get 0->2 (parent event continues with the updated value) **Recursive change** (see https://continuously.dev/blog/2015/02/10/val-a-better-observablevalue.html) The code IntegerProperty p = new SimpleIntegerProperty(0); // L1 p.addListener((obs, old, val) -> { if (val.intValue() > 0) { p.set(val.intValue() - 1); } }); // L2 p.addListener((obs, old, val) -> System.out.println(old + " -> " + val)); p.set(2); will trigger L1 0->2 (set 1) L1 2->1 (set 0) L1 2->0 L2 is not triggered because the updated event is 0->0 Nothing is printed instead of the current behavior that will print 1->0 2->0 0->0 ### Equality check Change events require a comparison method for the old and new value. The 2 candidates are reference equality (`==`) and object equality (`Objects#equals`). There is some inconsistency in JavaFX about how this equality check is made (it is made in a few places on a few different types). It makes sense to do `==` with primitive types, and `equals` with `String` and the primitive wrappers. For other types, it depends on their characteristics. The "safer" option is `==` because a change that is triggered by `!=` can then be tested for `!oldValue.equals(newValue)` in the listener and be vetoed; the opposite is not possible. This might mean that the user will have to give the comparison method that is desired. Currently, `==` is used except for `String`. The behavior is preserved in this change, but will be investigated further in order to allows for more sensible change events. ### Performance Performance both in memory and speed is either equal or slightly worse than the current one. This is because the current behavior is wrong and fixing it entails more complications. In practice, the difference should be small. Registering many listeners on the same observable is not recommended and has caused issues in the past as well. Performance is a WIP and benchmarks will be posted later. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1081#issuecomment-1507215618 From jhendrikx at openjdk.org Sat Apr 15 19:33:53 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sat, 15 Apr 2023 19:33:53 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs In-Reply-To: References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: On Thu, 13 Apr 2023 15:58:32 GMT, Nir Lisker wrote: > John and I discussed this off-list. I will write a short review of this change. I have some small corrections I think. > * Nested events are invoked "depth-first", meaning that the parent event propagation is halted until the nested event finishes (see below). **This differs from the current behavior that takes the "breadth-first" approach** - each event finishes before the nested one starts (buggy implementation). Current behavior in `ExpressionHelper` is also depth first. > ### Equality check > Change events require a comparison method for the old and new value. The 2 candidates are reference equality (`==`) and object equality (`Objects#equals`). There is some inconsistency in JavaFX about how this equality check is made (it is made in a few places on a few different types). It makes sense to do `==` with primitive types, and `equals` with `String` and the primitive wrappers. For other types, it depends on their characteristics. The "safer" option is `==` because a change that is triggered by `!=` can then be tested for `!oldValue.equals(newValue)` in the listener and be vetoed; the opposite is not possible. This might mean that the user will have to give the comparison method that is desired. > > Currently, `==` is used except for `String`. The behavior is preserved in this change, but will be investigated further in order to allows for more sensible change events. Just to add here, there are actually two checks involved. When you "set" the value on a property, all properties do a reference equality check (apart from String) to determine whether to fire their listeners. This means that `InvalidationListener`s always fire in these circumstances. Change listeners however are protected by a 2nd check that is part of `ExpressionHelper`. This check uses `equals` for all property types. This means that the behavior of an `InvalidationListener` + `get` is sometimes subtly different from using a `ChangeListener`. When looking only at change listeners, this behavior makes sense for any type that is either primitive, immutable or mutable without overriding `equals`. For types that are mutable **and** override `equals`, the odd situation can occur that no change fires because the two instances are equal, but that the instance reference did change. When such a type is mutable, any further mutations could be missed. Simple example: List a = new ArrayList<>(); List b = a.clone(); ObjectProperty prop = new SimpleObjectProperty<>(a); ObjectProperty copy = new SimpleObjectProperty<>(a); // keep properties in sync: prop.addListener((obs, o, n) -> copy.set(n)); prop.get().equals(copy.get()); // true :-) // change first property: prop.set(b); // no change fired, they're equals! b.add("Hello"); prop.get().equals(copy.get()); // false, as prop has reference B, while copy has reference A still... It doesn't happen too often that properties are used with a type that is mutable with its own `equals` implementation, so this usually works correctly; for cases where you do want to use a mutable type with its own `equals` in an `ObjectProperty` though, I think having a variant of `ObjectProperty` with a reference equality check for its change listeners call may be sufficient. > ### Performance > Performance both in memory and speed is either equal or slightly worse than the current one. This is because the current behavior is wrong and fixing it entails more complications. In practice, the difference should be small. Registering many listeners on the same observable is not recommended and has caused issues in the past as well. Performance is a WIP and benchmarks will be posted later. The implementation is able to avoid using a wrapper for single invalidation/change listeners, which improves memory use a bit for the second most common state properties are in (having 1 listener only -- the most common state being having no listeners at all). As for adding/removing many listeners, I've have changed my stance on this and I don't think we should cater to situations that can have 10.000's of listeners -- even if add/remove performance was much improved, that won't make notifying such high amounts of listeners any better. Having such high amounts of listeners on a single property is a sign that something is wrong with the design, and even if it were to perform reasonably (which it won't due to the sheer amount of listener calls), it would be better to investigate how to avoid adding so many listeners, perhaps by adding a single listener and distributing the requested information more directly (via a shared model for example). This implementation will have similar performance when it comes to adding/removing listeners as the current implementation. It grows and shrinks the listener list on demand, with the major difference being that when the list is locked (due to an ongoing notification) it will avoid modifying the lists in such a way that indices of current listeners change (removals are `null`ed out). After the list unlocks, the list is compacted if there were any listener additions/removals, and `null`s (and weak listeners) are removed at that time. For this reason it may win out in some cases where listeners are added/removed during notifications, as it does not need to make copies of the listener list, but that is going to be a very rare occurrence. ------------- PR Comment: https://git.openjdk.org/jfx/pull/1081#issuecomment-1507339488 From tsayao at openjdk.org Sat Apr 15 23:05:40 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sat, 15 Apr 2023 23:05:40 GMT Subject: RFR: 8305768: Unify WindowContext in glass-gtk [v2] In-Reply-To: References: Message-ID: On Sat, 8 Apr 2023 01:03:53 GMT, Thiago Milczarek Sayao wrote: >> This unifies and organizes WindowContext of the glass-gtk. >> >> It does not change any behaviour, just reorganizes the code. > > Thiago Milczarek Sayao has updated the pull request incrementally with one additional commit since the last revision: > > Unrelated file modules/javafx.graphics/src/main/native-glass/gtk/glass_window.cpp line 126: > 124: geometry(), > 125: resizable(), > 126: jview(NULL) { For some reason if `jview` is not initialized as `NULL`, `set_view`crashes. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1085#discussion_r1167647317 From tsayao at openjdk.org Sat Apr 15 23:23:40 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sat, 15 Apr 2023 23:23:40 GMT Subject: RFR: 8305768: Unify WindowContext in glass-gtk [v3] In-Reply-To: References: Message-ID: > This unifies and organizes WindowContext of the glass-gtk. > > It does not change any behaviour, just reorganizes the code. Thiago Milczarek Sayao has updated the pull request incrementally with one additional commit since the last revision: Initialize variables ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1085/files - new: https://git.openjdk.org/jfx/pull/1085/files/102592e6..34656b03 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1085&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1085&range=01-02 Stats: 25 lines in 2 files changed: 16 ins; 8 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1085.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1085/head:pull/1085 PR: https://git.openjdk.org/jfx/pull/1085 From tsayao at openjdk.org Sat Apr 15 23:32:42 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sat, 15 Apr 2023 23:32:42 GMT Subject: RFR: 8223373: Remove IntelliJ IDEA specific files from the source code repository [v5] In-Reply-To: <0I3XY4IbGS1qi4H52ZP5fFhJ_5thQyrYVsgc9tmFVus=.3ac1bc99-1782-46fd-98a5-30c0f847b1a1@github.com> References: <3zCUdkkbxcB1NMO9-VFrOgALNGa4k2vC0yXoyqYSbyQ=.596e4f9c-9101-4548-9d7e-134f06d1770c@github.com> <0I3XY4IbGS1qi4H52ZP5fFhJ_5thQyrYVsgc9tmFVus=.3ac1bc99-1782-46fd-98a5-30c0f847b1a1@github.com> Message-ID: On Fri, 14 Apr 2023 16:14:36 GMT, Marius Hanl wrote: >> .gitignore line 57: >> >>> 55: >>> 56: # IntelliJ >>> 57: out/ >> >> This would pick up more than just IntelliJ files. Are they all needed? > > `out` is the default `Compiler output` path in IntelliJ. But I don't think it is really needed here. Updated it, `*.iml` and `*.ipr` are the Idea project files that are created when importing from gradle. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1009#discussion_r1167667445 From tsayao at openjdk.org Sat Apr 15 23:32:40 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sat, 15 Apr 2023 23:32:40 GMT Subject: RFR: 8223373: Remove IntelliJ IDEA specific files from the source code repository [v6] In-Reply-To: References: Message-ID: > This PR does: > > - Remove specific Idea files and let it be imported from gradle; > - Adds checkstyle (to use with checkstyle plugin - it will let you know style mistakes); > - Configures auto-format to sun style (with the changes mentioned in [Code Style Rules](https://wiki.openjdk.org/display/OpenJFX/Code+Style+Rules)); > - Automatically sets Copyright notice (updates year too); > - Run configurations for samples/toys and builds. Thiago Milczarek Sayao has updated the pull request incrementally with two additional commits since the last revision: - Update .gitignore - Remove unrelated gitignore ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1009/files - new: https://git.openjdk.org/jfx/pull/1009/files/e4c7b4ed..ec5d0ab1 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1009&range=05 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1009&range=04-05 Stats: 9 lines in 1 file changed: 0 ins; 9 del; 0 mod Patch: https://git.openjdk.org/jfx/pull/1009.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1009/head:pull/1009 PR: https://git.openjdk.org/jfx/pull/1009 From tsayao at openjdk.org Sat Apr 15 23:32:44 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sat, 15 Apr 2023 23:32:44 GMT Subject: RFR: 8223373: Remove IntelliJ IDEA specific files from the source code repository [v5] In-Reply-To: References: <3zCUdkkbxcB1NMO9-VFrOgALNGa4k2vC0yXoyqYSbyQ=.596e4f9c-9101-4548-9d7e-134f06d1770c@github.com> Message-ID: <_0vRPBrCnpKYIHbY9gJ-UKdudSRj7ioFAMZjs5mgJKk=.12dfcb3e-0416-4b17-a712-c2b7eb9b489a@github.com> On Fri, 7 Apr 2023 22:40:32 GMT, Kevin Rushforth wrote: >> Thiago Milczarek Sayao has updated the pull request incrementally with two additional commits since the last revision: >> >> - Revert "Make intellij see :systemTests dependecies" >> >> This reverts commit dca7eab24958e1214147b7d291f0faf52ea27ddf. >> - Make intellij see :systemTests dependecies > > .gitignore line 67: > >> 65: >> 66: #mac folder >> 67: .DS_Store > > These seem unrelated to this PR (and in the case of `hs_err`, there is a typo). Removed them > checkstyle.xml line 1: > >> 1: > > I'm not keen on adding yet another top-level file in our repo. Can it go somewhere else? I've looked for a place, but didn't found one that would make sense. It could be used on eclipse as well and probably on netbeans. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1009#discussion_r1167667502 PR Review Comment: https://git.openjdk.org/jfx/pull/1009#discussion_r1167667672 From tsayao at openjdk.org Sat Apr 15 23:46:47 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sat, 15 Apr 2023 23:46:47 GMT Subject: RFR: 8273379: GTK3 stops sending key events during drag and drop [v29] In-Reply-To: <1ySLcmYQrCbbeTXzcs85mOxbbUy3PuBC1yxynkHvwrA=.cc4042ab-0be8-44a6-97d0-cf0f14804674@github.com> References: <8LJW64tevDxuYXe4HIfvvcCDZGcsv5imKtGkS9QdLmM=.44259629-6ed0-49c9-9e53-8faa7f9858e6@github.com> <1ySLcmYQrCbbeTXzcs85mOxbbUy3PuBC1yxynkHvwrA=.cc4042ab-0be8-44a6-97d0-cf0f14804674@github.com> Message-ID: On Sun, 12 Mar 2023 23:04:19 GMT, Thiago Milczarek Sayao wrote: >> This PR fixes 8273379. >> >> I reverted back to use GDK (from [8225571](https://bugs.openjdk.org/browse/JDK-8225571)) to handle the events. >> >> It may also fix [8280383](https://bugs.openjdk.org/browse/JDK-8280383). >> >> There's also some cleaup. >> >> To do general testing (two tests were added): >> `java @build/run.args -jar apps/toys/DragDrop/dist/DragDrop.jar` >> >> Information for reviewing: >> * Previously an offscreen window where used to pass events. Now it gets the window were Drag initially started (`WindowContextBase::sm_mouse_drag_window`); >> * There's a new `DragSourceContext` instead of global variables; >> * DragView were simplified; >> * It handles `GDK_GRAB_BROKEN` events (I still need to figure it out a test case for this - It should happen when another window grabs the device during the drag); >> * There's a special case for `GDK_BUTTON_RELEASE` because `WindowContext` will notify java about the button release and set `DnDGesture` to null before the end of the DND. >> * `gdk_drag_find_window_for_screen` -> pass the DragView window to be ignored (as it would "steal" destination motion events); >> * The Scenario were the drag source window closes during the drag is now covered; >> * It does not rely on `gdk_threads_add_idle` because it may be inconsistent. >> >> >> ![image](https://user-images.githubusercontent.com/30704286/213877115-18f274ff-18c9-4d38-acc4-449f24174ecc.png) >> ![image](https://user-images.githubusercontent.com/30704286/213877140-1d24c293-d70f-46e6-b040-c49170d2aa9a.png) > > Thiago Milczarek Sayao has updated the pull request incrementally with one additional commit since the last revision: > > Don't call gdk_device_manager_get_client_pointer() on event processing modules/javafx.graphics/src/main/native-glass/gtk/glass_dnd.cpp line 780: > 778: dnd_set_performed_action(translate_gdk_action_to_glass(action)); > 779: } > 780: gdk_threads_add_idle((GSourceFunc) dnd_destroy_drag_widget_callback, NULL); This could lead to inconsistent results. modules/javafx.graphics/src/main/native-glass/gtk/glass_dnd.cpp line 789: > 787: { > 788: dnd_set_performed_action(com_sun_glass_ui_gtk_GtkDnDClipboard_ACTION_NONE); > 789: gdk_threads_add_idle((GSourceFunc) dnd_destroy_drag_widget_callback, NULL); May cause problems. modules/javafx.graphics/src/main/native-glass/gtk/glass_dnd.cpp line 834: > 832: // be destroyed on drag end > 833: drag_widget = gtk_window_new(GTK_WINDOW_POPUP); > 834: gtk_window_resize(GTK_WINDOW(drag_widget), 1, 1); This was hacky. modules/javafx.graphics/src/main/native-glass/gtk/glass_dnd.cpp line 879: > 877: if (cursor == NULL) { > 878: cursor = gdk_cursor_new_from_name(gdk_display_get_default(), "dnd-none"); > 879: } Those cursor works on Ubuntu 16.04+ (probably before) and are consistent with the ones used on gnome. modules/javafx.graphics/src/main/native-glass/gtk/glass_dnd.cpp line 937: > 935: ERROR0("Drag not started on source window."); > 936: return; > 937: } Instead of using a offscreen window to pass events, it uses the window were the drag started, which seems the intended way. modules/javafx.graphics/src/main/native-glass/gtk/glass_dnd.cpp line 981: > 979: "text-x-generic", w, > 980: GTK_ICON_LOOKUP_USE_BUILTIN, > 981: &error); This adds the default dnd icon if no dragview is present. modules/javafx.graphics/src/main/native-glass/gtk/glass_dnd.cpp line 1024: > 1022: case GDK_GRAB_BROKEN: > 1023: process_dnd_source_grab_broken(ctx, event); > 1024: break; This was added to consider the case when a mouse grab is broken, I just could not think when it happens - but it's present on gdk managed drag and drop code. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/986#discussion_r1167668422 PR Review Comment: https://git.openjdk.org/jfx/pull/986#discussion_r1167668911 PR Review Comment: https://git.openjdk.org/jfx/pull/986#discussion_r1167668780 PR Review Comment: https://git.openjdk.org/jfx/pull/986#discussion_r1167668852 PR Review Comment: https://git.openjdk.org/jfx/pull/986#discussion_r1167668226 PR Review Comment: https://git.openjdk.org/jfx/pull/986#discussion_r1167668562 PR Review Comment: https://git.openjdk.org/jfx/pull/986#discussion_r1167668369 From tsayao at openjdk.org Sat Apr 15 23:53:47 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sat, 15 Apr 2023 23:53:47 GMT Subject: RFR: 8273379: GTK3 stops sending key events during drag and drop [v29] In-Reply-To: <1ySLcmYQrCbbeTXzcs85mOxbbUy3PuBC1yxynkHvwrA=.cc4042ab-0be8-44a6-97d0-cf0f14804674@github.com> References: <8LJW64tevDxuYXe4HIfvvcCDZGcsv5imKtGkS9QdLmM=.44259629-6ed0-49c9-9e53-8faa7f9858e6@github.com> <1ySLcmYQrCbbeTXzcs85mOxbbUy3PuBC1yxynkHvwrA=.cc4042ab-0be8-44a6-97d0-cf0f14804674@github.com> Message-ID: On Sun, 12 Mar 2023 23:04:19 GMT, Thiago Milczarek Sayao wrote: >> This PR fixes 8273379. >> >> I reverted back to use GDK (from [8225571](https://bugs.openjdk.org/browse/JDK-8225571)) to handle the events. >> >> It may also fix [8280383](https://bugs.openjdk.org/browse/JDK-8280383). >> >> There's also some cleaup. >> >> To do general testing (two tests were added): >> `java @build/run.args -jar apps/toys/DragDrop/dist/DragDrop.jar` >> >> Information for reviewing: >> * Previously an offscreen window where used to pass events. Now it gets the window were Drag initially started (`WindowContextBase::sm_mouse_drag_window`); >> * There's a new `DragSourceContext` instead of global variables; >> * DragView were simplified; >> * It handles `GDK_GRAB_BROKEN` events (I still need to figure it out a test case for this - It should happen when another window grabs the device during the drag); >> * There's a special case for `GDK_BUTTON_RELEASE` because `WindowContext` will notify java about the button release and set `DnDGesture` to null before the end of the DND. >> * `gdk_drag_find_window_for_screen` -> pass the DragView window to be ignored (as it would "steal" destination motion events); >> * The Scenario were the drag source window closes during the drag is now covered; >> * It does not rely on `gdk_threads_add_idle` because it may be inconsistent. >> >> >> ![image](https://user-images.githubusercontent.com/30704286/213877115-18f274ff-18c9-4d38-acc4-449f24174ecc.png) >> ![image](https://user-images.githubusercontent.com/30704286/213877140-1d24c293-d70f-46e6-b040-c49170d2aa9a.png) > > Thiago Milczarek Sayao has updated the pull request incrementally with one additional commit since the last revision: > > Don't call gdk_device_manager_get_client_pointer() on event processing modules/javafx.graphics/src/main/native-glass/gtk/glass_dnd.cpp line 817: > 815: if (ctx->drag_view) { > 816: ctx->drag_view->move(x_root, y_root); > 817: ignore = ctx->drag_view->get_window(); This tells GDK to ignore the drag view as a possible destination because it's under the cursor. modules/javafx.graphics/src/main/native-glass/gtk/glass_general.h line 58: > 56: | GDK_BUTTON3_MOTION_MASK \ > 57: | GDK_BUTTON_PRESS_MASK \ > 58: | GDK_BUTTON_RELEASE_MASK) This unifies MOUSE events on one place. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/986#discussion_r1167669338 PR Review Comment: https://git.openjdk.org/jfx/pull/986#discussion_r1167669450 From tsayao at openjdk.org Sun Apr 16 00:03:47 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sun, 16 Apr 2023 00:03:47 GMT Subject: RFR: 8273379: GTK3 stops sending key events during drag and drop [v30] In-Reply-To: <8LJW64tevDxuYXe4HIfvvcCDZGcsv5imKtGkS9QdLmM=.44259629-6ed0-49c9-9e53-8faa7f9858e6@github.com> References: <8LJW64tevDxuYXe4HIfvvcCDZGcsv5imKtGkS9QdLmM=.44259629-6ed0-49c9-9e53-8faa7f9858e6@github.com> Message-ID: <0eU_meshxVH1urcrxUFv4rB-7Rm687Pr7eyRJN6IMUQ=.39d9f337-2291-4d65-93f3-14e6a914efb9@github.com> > This PR fixes 8273379. > > I reverted back to use GDK (from [8225571](https://bugs.openjdk.org/browse/JDK-8225571)) to handle the events. > > It may also fix [8280383](https://bugs.openjdk.org/browse/JDK-8280383). > > There's also some cleaup. > > To do general testing (two tests were added): > `java @build/run.args -jar apps/toys/DragDrop/dist/DragDrop.jar` > > Information for reviewing: > * Previously an offscreen window where used to pass events. Now it gets the window were Drag initially started (`WindowContextBase::sm_mouse_drag_window`); > * There's a new `DragSourceContext` instead of global variables; > * DragView were simplified; > * It handles `GDK_GRAB_BROKEN` events (I still need to figure it out a test case for this - It should happen when another window grabs the device during the drag); > * There's a special case for `GDK_BUTTON_RELEASE` because `WindowContext` will notify java about the button release and set `DnDGesture` to null before the end of the DND. > * `gdk_drag_find_window_for_screen` -> pass the DragView window to be ignored (as it would "steal" destination motion events); > * The Scenario were the drag source window closes during the drag is now covered; > * It does not rely on `gdk_threads_add_idle` because it may be inconsistent. > > > ![image](https://user-images.githubusercontent.com/30704286/213877115-18f274ff-18c9-4d38-acc4-449f24174ecc.png) > ![image](https://user-images.githubusercontent.com/30704286/213877140-1d24c293-d70f-46e6-b040-c49170d2aa9a.png) Thiago Milczarek Sayao has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 76 commits: - Merge branch 'master' into 8273379-dnd-keys - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Merge branch 'openjdk:master' into master - Don't call gdk_device_manager_get_client_pointer() on event processing - ... and 66 more: https://git.openjdk.org/jfx/compare/0c03a411...2302657e ------------- Changes: https://git.openjdk.org/jfx/pull/986/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=986&range=29 Stats: 962 lines in 9 files changed: 611 ins; 177 del; 174 mod Patch: https://git.openjdk.org/jfx/pull/986.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/986/head:pull/986 PR: https://git.openjdk.org/jfx/pull/986 From tsayao at openjdk.org Sun Apr 16 00:03:48 2023 From: tsayao at openjdk.org (Thiago Milczarek Sayao) Date: Sun, 16 Apr 2023 00:03:48 GMT Subject: RFR: 8273379: GTK3 stops sending key events during drag and drop [v29] In-Reply-To: <1ySLcmYQrCbbeTXzcs85mOxbbUy3PuBC1yxynkHvwrA=.cc4042ab-0be8-44a6-97d0-cf0f14804674@github.com> References: <8LJW64tevDxuYXe4HIfvvcCDZGcsv5imKtGkS9QdLmM=.44259629-6ed0-49c9-9e53-8faa7f9858e6@github.com> <1ySLcmYQrCbbeTXzcs85mOxbbUy3PuBC1yxynkHvwrA=.cc4042ab-0be8-44a6-97d0-cf0f14804674@github.com> Message-ID: <8IbhKZAVAVvUFRfkzfYUlE930Padp6yKoOHyeBael1M=.c11e93ca-08b8-4887-b1d8-c8a702f94fb7@github.com> On Sun, 12 Mar 2023 23:04:19 GMT, Thiago Milczarek Sayao wrote: >> This PR fixes 8273379. >> >> I reverted back to use GDK (from [8225571](https://bugs.openjdk.org/browse/JDK-8225571)) to handle the events. >> >> It may also fix [8280383](https://bugs.openjdk.org/browse/JDK-8280383). >> >> There's also some cleaup. >> >> To do general testing (two tests were added): >> `java @build/run.args -jar apps/toys/DragDrop/dist/DragDrop.jar` >> >> Information for reviewing: >> * Previously an offscreen window where used to pass events. Now it gets the window were Drag initially started (`WindowContextBase::sm_mouse_drag_window`); >> * There's a new `DragSourceContext` instead of global variables; >> * DragView were simplified; >> * It handles `GDK_GRAB_BROKEN` events (I still need to figure it out a test case for this - It should happen when another window grabs the device during the drag); >> * There's a special case for `GDK_BUTTON_RELEASE` because `WindowContext` will notify java about the button release and set `DnDGesture` to null before the end of the DND. >> * `gdk_drag_find_window_for_screen` -> pass the DragView window to be ignored (as it would "steal" destination motion events); >> * The Scenario were the drag source window closes during the drag is now covered; >> * It does not rely on `gdk_threads_add_idle` because it may be inconsistent. >> >> >> ![image](https://user-images.githubusercontent.com/30704286/213877115-18f274ff-18c9-4d38-acc4-449f24174ecc.png) >> ![image](https://user-images.githubusercontent.com/30704286/213877140-1d24c293-d70f-46e6-b040-c49170d2aa9a.png) > > Thiago Milczarek Sayao has updated the pull request incrementally with one additional commit since the last revision: > > Don't call gdk_device_manager_get_client_pointer() on event processing modules/javafx.graphics/src/main/native-glass/gtk/glass_dnd.h line 94: > 92: }; > 93: > 94: DragSourceContext() : last_x(0), last_y(0) {} `DragSourceContext` organizes variables in one place. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/986#discussion_r1167669902 From mstrauss at openjdk.org Sun Apr 16 04:22:58 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sun, 16 Apr 2023 04:22:58 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs In-Reply-To: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: On Tue, 4 Apr 2023 15:22:48 GMT, John Hendrikx wrote: > This provides and uses a new implementation of `ExpressionHelper`, called `ListenerManager` with improved semantics. > > # Behavior > > |Listener...|ExpressionHelper|ListenerManager| > |---|---|---| > |Invocation Order|In order they were registered, invalidation listeners always before change listeners|(unchanged)| > |Removal during Notification|All listeners present when notification started are notified, but excluded for any nested changes|Listeners are removed immediately regardless of nesting| > |Addition during Notification|Only listeners present when notification started are notified, but included for any nested changes|New listeners are never called during the current notification regardless of nesting| > > ## Nested notifications: > > | |ExpressionHelper|ListenerManager| > |---|---|---| > |Type|Depth first (call stack increases for each nested level)|(same)| > |# of Calls|Listeners * Depth (using incorrect old values)|Collapses nested changes, skipping non-changes| > |Vetoing Possible?|No|Yes| > |Old Value correctness|Only for listeners called before listeners making nested changes|Always| > > # Performance > > |Listener|ExpressionHelper|ListenerManager| > |---|---|---| > |Addition|Array based, append in empty slot, resize as needed|(same)| > |Removal|Array based, shift array, resize as needed|(same)| > |Addition during notification|Array is copied, removing collected WeakListeneres in the process|Tracked (append at end)| > |Removal during notification|As above|Entry is `null`ed| > |Notification completion with changes|-|Null entries (and collected WeakListeners) are removed| > |Notifying Invalidation Listeners|1 ns each|(same)| > |Notifying Change Listeners|1 ns each (*)|2-3 ns each| > > (*) a simple for loop is close to optimal, but unfortunately does not provide correct old values > > # Memory Use > > Does not include alignment, and assumes a 32-bit VM or one that is using compressed oops. > > |Listener|ExpressionHelper|ListenerManager|OldValueCaching ListenerManager| > |---|---|---|---| > |No Listeners|none|none|none| > |Single InvalidationListener|16 bytes overhead|none|none| > |Single ChangeListener|20 bytes overhead|none|16 bytes overhead| > |Multiple listeners|57 + 4 per listener (excluding unused slots)|57 + 4 per listener (excluding unused slots)|61 + 4 per listener (excluding unused slots)| > > # About nested changes > > Nested changes are simply changes that are made to a property that is currently in the process of notifying its listeners. This all occurs on the same thread, and a nested change is nothing more than the same property being modified, triggering its listeners again deeper in the call stack with another notification, while higher up the call stack a notification is still being handled: > > (top of stack) > fireValueChangedEvent (property A) <-- nested notification > setValue (property A) <-- listener modifies property A > changed (Listener 1) <-- a listener called by original notification > fireValueChangedEvent (property A) <-- original notification > > ## How do nested changes look? > > Let's say we have three listeners, where the middle listener changes values to uppercase. When changing a property with the initial value "A" to a lowercase "b" the listeners would see the following events: > > ### ExpressionHelper > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | | > | 1 |T5 | | |b -> B| | > | 0 |T6 | | |A -> B|Top level loop is resumed| > > Note how the values received by the 3rd listener are non-sensical. It receives two changes both of which changes to B from old values that are out of order. > > ### ListenerManager (new) > This how ListenerManager sends out these events: > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | The nested loop is terminated early at this point | > | 0 |T5 | | |A -> B|Top level loop is resumed| > > Note how the 3rd listener now receives an event that reflects what actually happened from its perspective. Also note that less events overall needed to be send out. > > # About Invocation Order > > A lot of code depends on the fact that an earlier registered listener of the same type is called **before** a later registered later of the same type. For listeners of different types it is a bit less clear. What is clear however is that invalidation and change listeners are defined by separate interfaces. Mixing their invocations (to conserve registration order) would not make sense. Historically, invalidation listeners are called before change listeners. No doubt, code will be (unknowingly) relying on this in today's JavaFX applications so changing this is not recommended. Perhaps there is reason to say that invalidation listeners should be called first as they're defined by the super interface of `ObservableValue` which introduces change listeners. > > # About Listener Add/Remove performance > > Many discussions have happened in the past to improve the performance of removing listeners, ranging from using maps to ordered data structures with better remove performance. Often these solutions would subtly change the notification order, or increase the overhead per listener significantly. > > But these discussions never really looked at the other consequences of having tens of thousands of listeners. Even if listeners could be removed in something approaching O(1) time (additions are already O(1) and so are not the issue), what about the performance of notifying that many listeners? That will still be O(n), and so even if JavaFX could handle addition and removal of that many listeners comfortably, actually using a property with that many listeners is still impossible as it would block the FX thread for far too long when sending out that many notifications. > > Therefore, I'm of the opinion that "fixing" this "problem" is pointless. Instead, having that many listeners should be considered a design flaw in the application. A solution that registers only a single listener that updates a shared model may be much more appropriate. > > # About Old Value Correctness > ...and why it is important. > > A change listener provides a callback that gives the old and the new value. One may reasonably expect that these values are never the same, and one may reasonably expect that the given old value is the same as the previous invocation's new value (if there was a previous invocation). > > In JavaFX, many change listeners are used for important tasks, ranging from reverting changes in order to veto something, to registering and unregistering listeners on properties. Many of those change listeners do not care about the old value, but there are a significant number that use it and rely on it being correct. A common example is the registering of a listener on the "new" value, and removing the same listener from the "old" value in order to maintain a link to some other property that changes location: > > (obs, old, current) -> { > if (old != null) { > old.removeListener(x); > } > if (current != null) { > current.addListener(x); > } > } > > The above code looks bug free, and it would be if the provided old values are always correct. Unfortunately, this does not have to be the case. When a nested change is made (which can be made by a user registered listener on the same property), `ExpressionHelper` makes no effort to ensure that for all registered listener the received old and new values make sense. This leads to listeners being notified twice with the same "new" value for example, but with a different old value. Imagine the above listener receives the following change events: > > scene1 becomes scene3 > scene2 becomes scene3 > > The above code would remove its listeners from `scene1` and `scene2`, and register two listeners on `scene3`. This leads to the listener being called twice when something changes. When later the scene changes to `scene4`, it receives: > > scene3 becomes scene4 > > Because it registered its listener twice on `scene3`, and only removes one of them, it now has listeners on both `scene3` and `scene4`. > > Clearly it is incredibly important that changes make sense, or even simple code that looks innocuous becomes problematic. > > # The PR > > The `ListenerManager` differs from `ExpressionHelper` in the following ways: > - Provides correct old/new values to `ChangeListener`s under all circumstances > - Unnecessary change events are never sent > - Single invalidation or change listeners are inlined directly into the observable class (in other words, properties with only a single listener don't take up any extra space at all) > - Performance is slightly worse when calling **change** listeners (but remember that `ExpressionHelper` is not following the contract). > - Removed listeners are never called after being removed (even if they were part of the initial list when the notification triggered) > - Added listeners are only called when a new non-nested (top level) notification starts > - Locking and maintaining the listener list works a bit differently -- the main takeaway is that the list indices remain the same when modified during nested modifications, which allows using the same list no matter how deep the nesting > - No reference is stored to the ObservableValue and no copy is kept of the current value > - Memory use when there is more than 1 listener should be similar, and better when not > - Although complicated, the code is I think much better separated, and more focused on accomplishing a single task: > - `ListenerManager` manages the listener storage in property classes, and the transformation between the listener variants (it either uses listeners directly, or uses a `ListenerList` when there are multiple listeners). > - `ListenerListBase` handles the locking and compacting of its listener lists. > - `ListenerList` which extends `ListenerListBase` is only concerned with the recursion algorithm for notification. > - `ArrayManager` handles resizing and reallocating of arrays. > - There are variants of `ListenerList` and `ListenerManager` which can cache their old values when its not possible to supply these (this has a cost, and is what `ExpressionHelper` does by default). > > The notification mechanism deals with nested notifications by tracking how many listeners were notified already before the nested notification occurs. For example, if 5 listeners were notified, and then listener 5 makes a nested change, then in that nested change only the first 5 listeners are notified again (if they still exist). The nested loop is then terminated early, at which point the top level loop resumes: it continues where it left of and notifies listener 6 and so on. This ensures that all notifications are always correct, and that listeners that "veto" changes can effectively block later listeners from seeing those at all. > > For example, if the first listener always uppercases any received values, then any succeeding listeners will always see only uppercase values. The first listener receives two notifications (`X -> a` and `a -> A`), and the second receives only `X -> A`. Contrast this with the old `ExpressionHelper`, which sends odd notifications to the second listener (`a -> A` and `X -> A`, in that order). > > Unfortunately, due to a somewhat weird design choice in the PropertyBase classes, the strategy of not having to cache the "current value" (or old value) can't be used (it can only be used for Bindings for now). So there is another variant of this helper, called `OldValueCachingListenerHelper`, with some slight differences: > > - Has an extra field for storing the old value when there are any `ChangeListener`s active > - Can't store a `ChangeListener` inline; a minimal wrapper is needed to track the old value (ExpressionHelper does the same) This change is a great improvement over the current implementation, I'm looking forward to it. Some comments below: modules/javafx.base/src/main/java/com/sun/javafx/binding/ArrayManager.java line 58: > 56: * Constructs a new instance. > 57: * > 58: * @param accessor an {@link Accessor}, cannot be {@code null} There is no `accessor` parameter. modules/javafx.base/src/main/java/com/sun/javafx/binding/ArrayManager.java line 94: > 92: * > 93: * @param instance the instance it is located in, cannot be {@code null} > 94: * @param array the occupied slots of the array to set The parameter is named `occupiedSlots`, not `array`. modules/javafx.base/src/main/java/com/sun/javafx/binding/ArrayManager.java line 168: > 166: * @param instance a reference to the instance where the array is stored, cannot be {@code null} > 167: * @param index an index to remove, cannot be negative, or greater than or equal to the number of occupied slots > 168: * @returns the element that was removed, can be {@code null} if the element at the given index was {@code null} Should be `@return`. modules/javafx.base/src/main/java/com/sun/javafx/binding/ArrayManager.java line 217: > 215: * @param instance a reference to the instance where the array is stored, cannot be {@code null} > 216: * @param index an index, cannot be negative, or greater than or equal to the number of occupied slots > 217: * @returns the element at the given index, can be {@code null} if the element at the given index was {@code null} Should be `@return`. modules/javafx.base/src/main/java/com/sun/javafx/binding/ArrayManager.java line 238: > 236: * @param index an index to set, cannot be negative, or greater than or equal to the number of occupied slots > 237: * @param element an element to set, can be {@code null} > 238: * @returns the element that was previously at the given index, can be {@code null} if the element at the given index was {@code null} Should be `@return`. modules/javafx.base/src/main/java/com/sun/javafx/binding/ArrayManager.java line 374: > 372: while (needed > max) { > 373: min = mid; > 374: mid = max; These two lines don't seem to be useful, as neither `min` nor `mid` are ever accessed after this point. modules/javafx.base/src/main/java/com/sun/javafx/binding/ListenerListBase.java line 243: > 241: > 242: /** > 243: * Gets the {@link ChangeLisener} at the given index. This can be {@code null} if the Typo: `ChangeListener` modules/javafx.base/src/main/java/com/sun/javafx/binding/ListenerManager.java line 84: > 82: * @throws NullPointerException when listener is {@code null} > 83: */ > 84: public void addListener(I instance, ChangeListener listener) { The code of this method is a duplicate of `addListener(I, InvalidationListener)`. Maybe you could use a common implementation for both overloads. modules/javafx.base/src/main/java/com/sun/javafx/binding/ListenerManager.java line 125: > 123: > 124: /** > 125: * Notifies the listeners managed in the given instance.

Minor: unncessary `

` modules/javafx.base/src/main/java/com/sun/javafx/binding/OldValueCachingListenerList.java line 101: > 99: * notification otherwise {@code false} > 100: */ > 101: public boolean notifyListeners(ObservableValue observableValue) { The code in this method is _almost_ identical to `ListenerList.notifyListeners(ObservableValue, T)`. Given that this method is somewhat complex, I think it would be good to use a common implementation. This will help with code review, and decrease the chance that both methods diverge further with future modifications. modules/javafx.base/src/main/java/com/sun/javafx/binding/OldValueCachingListenerList.java line 164: > 162: } > 163: > 164: private void callInvalidationListener(ObservableValue instance, InvalidationListener listener) { This method is identical to `ListenerList.callInvalidationListener`. modules/javafx.base/src/main/java/com/sun/javafx/binding/OldValueCachingListenerList.java line 173: > 171: } > 172: > 173: private void callChangeListener(ObservableValue instance, ChangeListener changeListener, T oldValue, T newValue) { Again, _almost_ identical to `ListenerList.callChangeListener`. modules/javafx.base/src/main/java/javafx/beans/property/ObjectPropertyBase.java line 91: > 89: @Override > 90: public void addListener(InvalidationListener listener) { > 91: LISTENER_MANAGER.addListener((ObjectPropertyBase) this, listener); I think the unchecked casts here can be removed if `ListenerManagerBase` is declared as `ListenerManagerBase>`, and `OldValueCachingListenerManager` accordingly. Then the `LISTENER_MANAGER` instance can be parameterized as `OldValueCachingListenerManager>`. modules/javafx.base/src/main/java/javafx/beans/property/ReadOnlyObjectPropertyBase.java line 66: > 64: @Override > 65: public void addListener(InvalidationListener listener) { > 66: LISTENER_MANAGER.addListener((ReadOnlyObjectPropertyBase) this, listener); See the comment for `ObjectPropertyBase`. modules/javafx.base/src/main/java/javafx/beans/value/ObservableValueBase.java line 70: > 68: @Override > 69: public void addListener(InvalidationListener listener) { > 70: LISTENER_MANAGER.addListener((ObservableValueBase) this, listener); See the comment for `ObjectPropertyBase`. modules/javafx.base/src/test/java/test/com/sun/javafx/binding/ArrayManagerTest.java line 3: > 1: package test.com.sun.javafx.binding; > 2: > 3: import static org.junit.Assert.assertNull; Wrong import modules/javafx.base/src/test/java/test/com/sun/javafx/binding/ArrayManagerTest.java line 91: > 89: > 90: @Test > 91: void setSshouldRejectSettingIllegalIndices() { Typo: `Sshould` ------------- PR Review: https://git.openjdk.org/jfx/pull/1081#pullrequestreview-1386650763 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167686027 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167686153 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167686217 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167686291 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167686304 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167686565 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167686624 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167687366 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167687470 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167688825 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167688937 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167688953 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167690228 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167690295 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167690187 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167690735 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167690436 From jhendrikx at openjdk.org Sun Apr 16 07:14:54 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 07:14:54 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v2] In-Reply-To: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: <1EX0-WLBpdCMalY33bjqgWW3qhd3ZeljQrycrOa_VGM=.a90d915c-6833-423a-b0a3-91aed05e6f77@github.com> > This provides and uses a new implementation of `ExpressionHelper`, called `ListenerManager` with improved semantics. > > # Behavior > > |Listener...|ExpressionHelper|ListenerManager| > |---|---|---| > |Invocation Order|In order they were registered, invalidation listeners always before change listeners|(unchanged)| > |Removal during Notification|All listeners present when notification started are notified, but excluded for any nested changes|Listeners are removed immediately regardless of nesting| > |Addition during Notification|Only listeners present when notification started are notified, but included for any nested changes|New listeners are never called during the current notification regardless of nesting| > > ## Nested notifications: > > | |ExpressionHelper|ListenerManager| > |---|---|---| > |Type|Depth first (call stack increases for each nested level)|(same)| > |# of Calls|Listeners * Depth (using incorrect old values)|Collapses nested changes, skipping non-changes| > |Vetoing Possible?|No|Yes| > |Old Value correctness|Only for listeners called before listeners making nested changes|Always| > > # Performance > > |Listener|ExpressionHelper|ListenerManager| > |---|---|---| > |Addition|Array based, append in empty slot, resize as needed|(same)| > |Removal|Array based, shift array, resize as needed|(same)| > |Addition during notification|Array is copied, removing collected WeakListeneres in the process|Tracked (append at end)| > |Removal during notification|As above|Entry is `null`ed| > |Notification completion with changes|-|Null entries (and collected WeakListeners) are removed| > |Notifying Invalidation Listeners|1 ns each|(same)| > |Notifying Change Listeners|1 ns each (*)|2-3 ns each| > > (*) a simple for loop is close to optimal, but unfortunately does not provide correct old values > > # Memory Use > > Does not include alignment, and assumes a 32-bit VM or one that is using compressed oops. > > |Listener|ExpressionHelper|ListenerManager|OldValueCaching ListenerManager| > |---|---|---|---| > |No Listeners|none|none|none| > |Single InvalidationListener|16 bytes overhead|none|none| > |Single ChangeListener|20 bytes overhead|none|16 bytes overhead| > |Multiple listeners|57 + 4 per listener (excluding unused slots)|57 + 4 per listener (excluding unused slots)|61 + 4 per listener (excluding unused slots)| > > # About nested changes > > Nested changes are simply changes that are made to a property that is currently in the process of notifying its listeners. This all occurs on the same thread, and a nested change is nothing more than the same property being modified, triggering its listeners again deeper in the call stack with another notification, while higher up the call stack a notification is still being handled: > > (top of stack) > fireValueChangedEvent (property A) <-- nested notification > setValue (property A) <-- listener modifies property A > changed (Listener 1) <-- a listener called by original notification > fireValueChangedEvent (property A) <-- original notification > > ## How do nested changes look? > > Let's say we have three listeners, where the middle listener changes values to uppercase. When changing a property with the initial value "A" to a lowercase "b" the listeners would see the following events: > > ### ExpressionHelper > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | | > | 1 |T5 | | |b -> B| | > | 0 |T6 | | |A -> B|Top level loop is resumed| > > Note how the values received by the 3rd listener are non-sensical. It receives two changes both of which changes to B from old values that are out of order. > > ### ListenerManager (new) > This how ListenerManager sends out these events: > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | The nested loop is terminated early at this point | > | 0 |T5 | | |A -> B|Top level loop is resumed| > > Note how the 3rd listener now receives an event that reflects what actually happened from its perspective. Also note that less events overall needed to be send out. > > # About Invocation Order > > A lot of code depends on the fact that an earlier registered listener of the same type is called **before** a later registered later of the same type. For listeners of different types it is a bit less clear. What is clear however is that invalidation and change listeners are defined by separate interfaces. Mixing their invocations (to conserve registration order) would not make sense. Historically, invalidation listeners are called before change listeners. No doubt, code will be (unknowingly) relying on this in today's JavaFX applications so changing this is not recommended. Perhaps there is reason to say that invalidation listeners should be called first as they're defined by the super interface of `ObservableValue` which introduces change listeners. > > # About Listener Add/Remove performance > > Many discussions have happened in the past to improve the performance of removing listeners, ranging from using maps to ordered data structures with better remove performance. Often these solutions would subtly change the notification order, or increase the overhead per listener significantly. > > But these discussions never really looked at the other consequences of having tens of thousands of listeners. Even if listeners could be removed in something approaching O(1) time (additions are already O(1) and so are not the issue), what about the performance of notifying that many listeners? That will still be O(n), and so even if JavaFX could handle addition and removal of that many listeners comfortably, actually using a property with that many listeners is still impossible as it would block the FX thread for far too long when sending out that many notifications. > > Therefore, I'm of the opinion that "fixing" this "problem" is pointless. Instead, having that many listeners should be considered a design flaw in the application. A solution that registers only a single listener that updates a shared model may be much more appropriate. > > # About Old Value Correctness > ...and why it is important. > > A change listener provides a callback that gives the old and the new value. One may reasonably expect that these values are never the same, and one may reasonably expect that the given old value is the same as the previous invocation's new value (if there was a previous invocation). > > In JavaFX, many change listeners are used for important tasks, ranging from reverting changes in order to veto something, to registering and unregistering listeners on properties. Many of those change listeners do not care about the old value, but there are a significant number that use it and rely on it being correct. A common example is the registering of a listener on the "new" value, and removing the same listener from the "old" value in order to maintain a link to some other property that changes location: > > (obs, old, current) -> { > if (old != null) { > old.removeListener(x); > } > if (current != null) { > current.addListener(x); > } > } > > The above code looks bug free, and it would be if the provided old values are always correct. Unfortunately, this does not have to be the case. When a nested change is made (which can be made by a user registered listener on the same property), `ExpressionHelper` makes no effort to ensure that for all registered listener the received old and new values make sense. This leads to listeners being notified twice with the same "new" value for example, but with a different old value. Imagine the above listener receives the following change events: > > scene1 becomes scene3 > scene2 becomes scene3 > > The above code would remove its listeners from `scene1` and `scene2`, and register two listeners on `scene3`. This leads to the listener being called twice when something changes. When later the scene changes to `scene4`, it receives: > > scene3 becomes scene4 > > Because it registered its listener twice on `scene3`, and only removes one of them, it now has listeners on both `scene3` and `scene4`. > > Clearly it is incredibly important that changes make sense, or even simple code that looks innocuous becomes problematic. > > # The PR > > The `ListenerManager` differs from `ExpressionHelper` in the following ways: > - Provides correct old/new values to `ChangeListener`s under all circumstances > - Unnecessary change events are never sent > - Single invalidation or change listeners are inlined directly into the observable class (in other words, properties with only a single listener don't take up any extra space at all) > - Performance is slightly worse when calling **change** listeners (but remember that `ExpressionHelper` is not following the contract). > - Removed listeners are never called after being removed (even if they were part of the initial list when the notification triggered) > - Added listeners are only called when a new non-nested (top level) notification starts > - Locking and maintaining the listener list works a bit differently -- the main takeaway is that the list indices remain the same when modified during nested modifications, which allows using the same list no matter how deep the nesting > - No reference is stored to the ObservableValue and no copy is kept of the current value > - Memory use when there is more than 1 listener should be similar, and better when not > - Although complicated, the code is I think much better separated, and more focused on accomplishing a single task: > - `ListenerManager` manages the listener storage in property classes, and the transformation between the listener variants (it either uses listeners directly, or uses a `ListenerList` when there are multiple listeners). > - `ListenerListBase` handles the locking and compacting of its listener lists. > - `ListenerList` which extends `ListenerListBase` is only concerned with the recursion algorithm for notification. > - `ArrayManager` handles resizing and reallocating of arrays. > - There are variants of `ListenerList` and `ListenerManager` which can cache their old values when its not possible to supply these (this has a cost, and is what `ExpressionHelper` does by default). > > The notification mechanism deals with nested notifications by tracking how many listeners were notified already before the nested notification occurs. For example, if 5 listeners were notified, and then listener 5 makes a nested change, then in that nested change only the first 5 listeners are notified again (if they still exist). The nested loop is then terminated early, at which point the top level loop resumes: it continues where it left of and notifies listener 6 and so on. This ensures that all notifications are always correct, and that listeners that "veto" changes can effectively block later listeners from seeing those at all. > > For example, if the first listener always uppercases any received values, then any succeeding listeners will always see only uppercase values. The first listener receives two notifications (`X -> a` and `a -> A`), and the second receives only `X -> A`. Contrast this with the old `ExpressionHelper`, which sends odd notifications to the second listener (`a -> A` and `X -> A`, in that order). > > Unfortunately, due to a somewhat weird design choice in the PropertyBase classes, the strategy of not having to cache the "current value" (or old value) can't be used (it can only be used for Bindings for now). So there is another variant of this helper, called `OldValueCachingListenerHelper`, with some slight differences: > > - Has an extra field for storing the old value when there are any `ChangeListener`s active > - Can't store a `ChangeListener` inline; a minimal wrapper is needed to track the old value (ExpressionHelper does the same) John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: - Fix incorrect import - Fix review comments ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1081/files - new: https://git.openjdk.org/jfx/pull/1081/files/351520f0..80f639d7 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=00-01 Stats: 19 lines in 5 files changed: 6 ins; 5 del; 8 mod Patch: https://git.openjdk.org/jfx/pull/1081.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1081/head:pull/1081 PR: https://git.openjdk.org/jfx/pull/1081 From jhendrikx at openjdk.org Sun Apr 16 07:14:55 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 07:14:55 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v2] In-Reply-To: References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: On Sun, 16 Apr 2023 03:21:59 GMT, Michael Strau? wrote: >> John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: >> >> - Fix incorrect import >> - Fix review comments > > modules/javafx.base/src/main/java/com/sun/javafx/binding/ArrayManager.java line 58: > >> 56: * Constructs a new instance. >> 57: * >> 58: * @param accessor an {@link Accessor}, cannot be {@code null} > > There is no `accessor` parameter. Thanks for all the Javadoc checks; I've turned on some IDE warnings for these as it turns out they're harder to get right than I thought :) I fixed a couple more as well. > modules/javafx.base/src/main/java/com/sun/javafx/binding/ArrayManager.java line 374: > >> 372: while (needed > max) { >> 373: min = mid; >> 374: mid = max; > > These two lines don't seem to be useful, as neither `min` nor `mid` are ever accessed after this point. Well spotted, they indeed are not needed in the 2nd loop. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167744831 PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167744922 From jhendrikx at openjdk.org Sun Apr 16 07:37:39 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 07:37:39 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v2] In-Reply-To: <0ZqMcHZ78UF04XZFUQ6H1yv016hFX_E9XvThZtAIwB8=.5822a500-5872-46a9-a315-8a4a509a91c7@github.com> References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> <0ZqMcHZ78UF04XZFUQ6H1yv016hFX_E9XvThZtAIwB8=.5822a500-5872-46a9-a315-8a4a509a91c7@github.com> Message-ID: On Sat, 15 Apr 2023 18:01:28 GMT, Michael Strau? wrote: >> This PR adds the following methods to the `EventTarget` interface: >> 1. `addEventHandler` >> 2. `removeEventHandler` >> 3. `addEventFilter` >> 4. `removeEventFilter` > > Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: > > revert a change in Menu Marked as reviewed by jhendrikx (Committer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1090#pullrequestreview-1386723590 From jhendrikx at openjdk.org Sun Apr 16 07:37:57 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 07:37:57 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v3] In-Reply-To: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: > This provides and uses a new implementation of `ExpressionHelper`, called `ListenerManager` with improved semantics. > > # Behavior > > |Listener...|ExpressionHelper|ListenerManager| > |---|---|---| > |Invocation Order|In order they were registered, invalidation listeners always before change listeners|(unchanged)| > |Removal during Notification|All listeners present when notification started are notified, but excluded for any nested changes|Listeners are removed immediately regardless of nesting| > |Addition during Notification|Only listeners present when notification started are notified, but included for any nested changes|New listeners are never called during the current notification regardless of nesting| > > ## Nested notifications: > > | |ExpressionHelper|ListenerManager| > |---|---|---| > |Type|Depth first (call stack increases for each nested level)|(same)| > |# of Calls|Listeners * Depth (using incorrect old values)|Collapses nested changes, skipping non-changes| > |Vetoing Possible?|No|Yes| > |Old Value correctness|Only for listeners called before listeners making nested changes|Always| > > # Performance > > |Listener|ExpressionHelper|ListenerManager| > |---|---|---| > |Addition|Array based, append in empty slot, resize as needed|(same)| > |Removal|Array based, shift array, resize as needed|(same)| > |Addition during notification|Array is copied, removing collected WeakListeneres in the process|Tracked (append at end)| > |Removal during notification|As above|Entry is `null`ed| > |Notification completion with changes|-|Null entries (and collected WeakListeners) are removed| > |Notifying Invalidation Listeners|1 ns each|(same)| > |Notifying Change Listeners|1 ns each (*)|2-3 ns each| > > (*) a simple for loop is close to optimal, but unfortunately does not provide correct old values > > # Memory Use > > Does not include alignment, and assumes a 32-bit VM or one that is using compressed oops. > > |Listener|ExpressionHelper|ListenerManager|OldValueCaching ListenerManager| > |---|---|---|---| > |No Listeners|none|none|none| > |Single InvalidationListener|16 bytes overhead|none|none| > |Single ChangeListener|20 bytes overhead|none|16 bytes overhead| > |Multiple listeners|57 + 4 per listener (excluding unused slots)|57 + 4 per listener (excluding unused slots)|61 + 4 per listener (excluding unused slots)| > > # About nested changes > > Nested changes are simply changes that are made to a property that is currently in the process of notifying its listeners. This all occurs on the same thread, and a nested change is nothing more than the same property being modified, triggering its listeners again deeper in the call stack with another notification, while higher up the call stack a notification is still being handled: > > (top of stack) > fireValueChangedEvent (property A) <-- nested notification > setValue (property A) <-- listener modifies property A > changed (Listener 1) <-- a listener called by original notification > fireValueChangedEvent (property A) <-- original notification > > ## How do nested changes look? > > Let's say we have three listeners, where the middle listener changes values to uppercase. When changing a property with the initial value "A" to a lowercase "b" the listeners would see the following events: > > ### ExpressionHelper > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | | > | 1 |T5 | | |b -> B| | > | 0 |T6 | | |A -> B|Top level loop is resumed| > > Note how the values received by the 3rd listener are non-sensical. It receives two changes both of which changes to B from old values that are out of order. > > ### ListenerManager (new) > This how ListenerManager sends out these events: > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | The nested loop is terminated early at this point | > | 0 |T5 | | |A -> B|Top level loop is resumed| > > Note how the 3rd listener now receives an event that reflects what actually happened from its perspective. Also note that less events overall needed to be send out. > > # About Invocation Order > > A lot of code depends on the fact that an earlier registered listener of the same type is called **before** a later registered later of the same type. For listeners of different types it is a bit less clear. What is clear however is that invalidation and change listeners are defined by separate interfaces. Mixing their invocations (to conserve registration order) would not make sense. Historically, invalidation listeners are called before change listeners. No doubt, code will be (unknowingly) relying on this in today's JavaFX applications so changing this is not recommended. Perhaps there is reason to say that invalidation listeners should be called first as they're defined by the super interface of `ObservableValue` which introduces change listeners. > > # About Listener Add/Remove performance > > Many discussions have happened in the past to improve the performance of removing listeners, ranging from using maps to ordered data structures with better remove performance. Often these solutions would subtly change the notification order, or increase the overhead per listener significantly. > > But these discussions never really looked at the other consequences of having tens of thousands of listeners. Even if listeners could be removed in something approaching O(1) time (additions are already O(1) and so are not the issue), what about the performance of notifying that many listeners? That will still be O(n), and so even if JavaFX could handle addition and removal of that many listeners comfortably, actually using a property with that many listeners is still impossible as it would block the FX thread for far too long when sending out that many notifications. > > Therefore, I'm of the opinion that "fixing" this "problem" is pointless. Instead, having that many listeners should be considered a design flaw in the application. A solution that registers only a single listener that updates a shared model may be much more appropriate. > > # About Old Value Correctness > ...and why it is important. > > A change listener provides a callback that gives the old and the new value. One may reasonably expect that these values are never the same, and one may reasonably expect that the given old value is the same as the previous invocation's new value (if there was a previous invocation). > > In JavaFX, many change listeners are used for important tasks, ranging from reverting changes in order to veto something, to registering and unregistering listeners on properties. Many of those change listeners do not care about the old value, but there are a significant number that use it and rely on it being correct. A common example is the registering of a listener on the "new" value, and removing the same listener from the "old" value in order to maintain a link to some other property that changes location: > > (obs, old, current) -> { > if (old != null) { > old.removeListener(x); > } > if (current != null) { > current.addListener(x); > } > } > > The above code looks bug free, and it would be if the provided old values are always correct. Unfortunately, this does not have to be the case. When a nested change is made (which can be made by a user registered listener on the same property), `ExpressionHelper` makes no effort to ensure that for all registered listener the received old and new values make sense. This leads to listeners being notified twice with the same "new" value for example, but with a different old value. Imagine the above listener receives the following change events: > > scene1 becomes scene3 > scene2 becomes scene3 > > The above code would remove its listeners from `scene1` and `scene2`, and register two listeners on `scene3`. This leads to the listener being called twice when something changes. When later the scene changes to `scene4`, it receives: > > scene3 becomes scene4 > > Because it registered its listener twice on `scene3`, and only removes one of them, it now has listeners on both `scene3` and `scene4`. > > Clearly it is incredibly important that changes make sense, or even simple code that looks innocuous becomes problematic. > > # The PR > > The `ListenerManager` differs from `ExpressionHelper` in the following ways: > - Provides correct old/new values to `ChangeListener`s under all circumstances > - Unnecessary change events are never sent > - Single invalidation or change listeners are inlined directly into the observable class (in other words, properties with only a single listener don't take up any extra space at all) > - Performance is slightly worse when calling **change** listeners (but remember that `ExpressionHelper` is not following the contract). > - Removed listeners are never called after being removed (even if they were part of the initial list when the notification triggered) > - Added listeners are only called when a new non-nested (top level) notification starts > - Locking and maintaining the listener list works a bit differently -- the main takeaway is that the list indices remain the same when modified during nested modifications, which allows using the same list no matter how deep the nesting > - No reference is stored to the ObservableValue and no copy is kept of the current value > - Memory use when there is more than 1 listener should be similar, and better when not > - Although complicated, the code is I think much better separated, and more focused on accomplishing a single task: > - `ListenerManager` manages the listener storage in property classes, and the transformation between the listener variants (it either uses listeners directly, or uses a `ListenerList` when there are multiple listeners). > - `ListenerListBase` handles the locking and compacting of its listener lists. > - `ListenerList` which extends `ListenerListBase` is only concerned with the recursion algorithm for notification. > - `ArrayManager` handles resizing and reallocating of arrays. > - There are variants of `ListenerList` and `ListenerManager` which can cache their old values when its not possible to supply these (this has a cost, and is what `ExpressionHelper` does by default). > > The notification mechanism deals with nested notifications by tracking how many listeners were notified already before the nested notification occurs. For example, if 5 listeners were notified, and then listener 5 makes a nested change, then in that nested change only the first 5 listeners are notified again (if they still exist). The nested loop is then terminated early, at which point the top level loop resumes: it continues where it left of and notifies listener 6 and so on. This ensures that all notifications are always correct, and that listeners that "veto" changes can effectively block later listeners from seeing those at all. > > For example, if the first listener always uppercases any received values, then any succeeding listeners will always see only uppercase values. The first listener receives two notifications (`X -> a` and `a -> A`), and the second receives only `X -> A`. Contrast this with the old `ExpressionHelper`, which sends odd notifications to the second listener (`a -> A` and `X -> A`, in that order). > > Unfortunately, due to a somewhat weird design choice in the PropertyBase classes, the strategy of not having to cache the "current value" (or old value) can't be used (it can only be used for Bindings for now). So there is another variant of this helper, called `OldValueCachingListenerHelper`, with some slight differences: > > - Has an extra field for storing the old value when there are any `ChangeListener`s active > - Can't store a `ChangeListener` inline; a minimal wrapper is needed to track the old value (ExpressionHelper does the same) John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: - Improve generics on ObservableValueBase - Improve generics ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1081/files - new: https://git.openjdk.org/jfx/pull/1081/files/80f639d7..89369d3f Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=01-02 Stats: 47 lines in 9 files changed: 3 ins; 0 del; 44 mod Patch: https://git.openjdk.org/jfx/pull/1081.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1081/head:pull/1081 PR: https://git.openjdk.org/jfx/pull/1081 From jhendrikx at openjdk.org Sun Apr 16 07:37:58 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 07:37:58 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v3] In-Reply-To: References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: On Sun, 16 Apr 2023 04:13:22 GMT, Michael Strau? wrote: >> John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: >> >> - Improve generics on ObservableValueBase >> - Improve generics > > modules/javafx.base/src/main/java/javafx/beans/property/ObjectPropertyBase.java line 91: > >> 89: @Override >> 90: public void addListener(InvalidationListener listener) { >> 91: LISTENER_MANAGER.addListener((ObjectPropertyBase) this, listener); > > I think the unchecked casts here can be removed if `ListenerManagerBase` is declared as `ListenerManagerBase>`, and `OldValueCachingListenerManager` accordingly. Then the `LISTENER_MANAGER` instance can be parameterized as `OldValueCachingListenerManager>`. Thanks, I gave up on that one a bit, I was looking for a better solution, but never got the generics quite the way I wanted them there, but your change works. I was primarily aiming to keep the casts as much out of the inner loops as possible. I still need to do one cast at this line, but it is a huge improvement: @Override public void addListener(ChangeListener listener) { LISTENER_MANAGER.addListener(this, (ChangeListener) listener); } ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167753159 From jhendrikx at openjdk.org Sun Apr 16 07:45:41 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 07:45:41 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v3] In-Reply-To: References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: On Sun, 16 Apr 2023 03:57:39 GMT, Michael Strau? wrote: >> John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: >> >> - Improve generics on ObservableValueBase >> - Improve generics > > modules/javafx.base/src/main/java/com/sun/javafx/binding/OldValueCachingListenerList.java line 101: > >> 99: * notification otherwise {@code false} >> 100: */ >> 101: public boolean notifyListeners(ObservableValue observableValue) { > > The code in this method is _almost_ identical to `ListenerList.notifyListeners(ObservableValue, T)`. > Given that this method is somewhat complex, I think it would be good to use a common implementation. > This will help with code review, and decrease the chance that both methods diverge further with future modifications. I agree with you there, and I've been looking what would be a good way to achieve this. I will take another look soon. My primary concern is that this is a somewhat critical path, and I would want to ensure that it doesn't cause too much performance regressions (I've already been optimizing all of this code with the help of a JMH test) ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167754712 From jhendrikx at openjdk.org Sun Apr 16 07:48:45 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 07:48:45 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v3] In-Reply-To: References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: <5AG9U6HB-zYePzKhbHX8SEk05fLFrRIAC1v8cImAmA8=.b8e80ad4-3d5a-4fab-b70b-1285e6f1061b@github.com> On Sun, 16 Apr 2023 03:59:09 GMT, Michael Strau? wrote: >> John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: >> >> - Improve generics on ObservableValueBase >> - Improve generics > > modules/javafx.base/src/main/java/com/sun/javafx/binding/OldValueCachingListenerList.java line 164: > >> 162: } >> 163: >> 164: private void callInvalidationListener(ObservableValue instance, InvalidationListener listener) { > > This method is identical to `ListenerList.callInvalidationListener`. Yes, it would be good to just put these static somewhere. They don't really fit well in the manager class (as the List class which doesn't depend on manager would need to call them there), and the other way around is also odd, given that I only need to call them when not in "list" mode. Still, putting them package private in the ListenerListBase could work.... ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167755526 From jhendrikx at openjdk.org Sun Apr 16 08:36:52 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 08:36:52 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v4] In-Reply-To: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: > This provides and uses a new implementation of `ExpressionHelper`, called `ListenerManager` with improved semantics. > > # Behavior > > |Listener...|ExpressionHelper|ListenerManager| > |---|---|---| > |Invocation Order|In order they were registered, invalidation listeners always before change listeners|(unchanged)| > |Removal during Notification|All listeners present when notification started are notified, but excluded for any nested changes|Listeners are removed immediately regardless of nesting| > |Addition during Notification|Only listeners present when notification started are notified, but included for any nested changes|New listeners are never called during the current notification regardless of nesting| > > ## Nested notifications: > > | |ExpressionHelper|ListenerManager| > |---|---|---| > |Type|Depth first (call stack increases for each nested level)|(same)| > |# of Calls|Listeners * Depth (using incorrect old values)|Collapses nested changes, skipping non-changes| > |Vetoing Possible?|No|Yes| > |Old Value correctness|Only for listeners called before listeners making nested changes|Always| > > # Performance > > |Listener|ExpressionHelper|ListenerManager| > |---|---|---| > |Addition|Array based, append in empty slot, resize as needed|(same)| > |Removal|Array based, shift array, resize as needed|(same)| > |Addition during notification|Array is copied, removing collected WeakListeneres in the process|Tracked (append at end)| > |Removal during notification|As above|Entry is `null`ed| > |Notification completion with changes|-|Null entries (and collected WeakListeners) are removed| > |Notifying Invalidation Listeners|1 ns each|(same)| > |Notifying Change Listeners|1 ns each (*)|2-3 ns each| > > (*) a simple for loop is close to optimal, but unfortunately does not provide correct old values > > # Memory Use > > Does not include alignment, and assumes a 32-bit VM or one that is using compressed oops. > > |Listener|ExpressionHelper|ListenerManager|OldValueCaching ListenerManager| > |---|---|---|---| > |No Listeners|none|none|none| > |Single InvalidationListener|16 bytes overhead|none|none| > |Single ChangeListener|20 bytes overhead|none|16 bytes overhead| > |Multiple listeners|57 + 4 per listener (excluding unused slots)|57 + 4 per listener (excluding unused slots)|61 + 4 per listener (excluding unused slots)| > > # About nested changes > > Nested changes are simply changes that are made to a property that is currently in the process of notifying its listeners. This all occurs on the same thread, and a nested change is nothing more than the same property being modified, triggering its listeners again deeper in the call stack with another notification, while higher up the call stack a notification is still being handled: > > (top of stack) > fireValueChangedEvent (property A) <-- nested notification > setValue (property A) <-- listener modifies property A > changed (Listener 1) <-- a listener called by original notification > fireValueChangedEvent (property A) <-- original notification > > ## How do nested changes look? > > Let's say we have three listeners, where the middle listener changes values to uppercase. When changing a property with the initial value "A" to a lowercase "b" the listeners would see the following events: > > ### ExpressionHelper > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | | > | 1 |T5 | | |b -> B| | > | 0 |T6 | | |A -> B|Top level loop is resumed| > > Note how the values received by the 3rd listener are non-sensical. It receives two changes both of which changes to B from old values that are out of order. > > ### ListenerManager (new) > This how ListenerManager sends out these events: > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | The nested loop is terminated early at this point | > | 0 |T5 | | |A -> B|Top level loop is resumed| > > Note how the 3rd listener now receives an event that reflects what actually happened from its perspective. Also note that less events overall needed to be send out. > > # About Invocation Order > > A lot of code depends on the fact that an earlier registered listener of the same type is called **before** a later registered later of the same type. For listeners of different types it is a bit less clear. What is clear however is that invalidation and change listeners are defined by separate interfaces. Mixing their invocations (to conserve registration order) would not make sense. Historically, invalidation listeners are called before change listeners. No doubt, code will be (unknowingly) relying on this in today's JavaFX applications so changing this is not recommended. Perhaps there is reason to say that invalidation listeners should be called first as they're defined by the super interface of `ObservableValue` which introduces change listeners. > > # About Listener Add/Remove performance > > Many discussions have happened in the past to improve the performance of removing listeners, ranging from using maps to ordered data structures with better remove performance. Often these solutions would subtly change the notification order, or increase the overhead per listener significantly. > > But these discussions never really looked at the other consequences of having tens of thousands of listeners. Even if listeners could be removed in something approaching O(1) time (additions are already O(1) and so are not the issue), what about the performance of notifying that many listeners? That will still be O(n), and so even if JavaFX could handle addition and removal of that many listeners comfortably, actually using a property with that many listeners is still impossible as it would block the FX thread for far too long when sending out that many notifications. > > Therefore, I'm of the opinion that "fixing" this "problem" is pointless. Instead, having that many listeners should be considered a design flaw in the application. A solution that registers only a single listener that updates a shared model may be much more appropriate. > > # About Old Value Correctness > ...and why it is important. > > A change listener provides a callback that gives the old and the new value. One may reasonably expect that these values are never the same, and one may reasonably expect that the given old value is the same as the previous invocation's new value (if there was a previous invocation). > > In JavaFX, many change listeners are used for important tasks, ranging from reverting changes in order to veto something, to registering and unregistering listeners on properties. Many of those change listeners do not care about the old value, but there are a significant number that use it and rely on it being correct. A common example is the registering of a listener on the "new" value, and removing the same listener from the "old" value in order to maintain a link to some other property that changes location: > > (obs, old, current) -> { > if (old != null) { > old.removeListener(x); > } > if (current != null) { > current.addListener(x); > } > } > > The above code looks bug free, and it would be if the provided old values are always correct. Unfortunately, this does not have to be the case. When a nested change is made (which can be made by a user registered listener on the same property), `ExpressionHelper` makes no effort to ensure that for all registered listener the received old and new values make sense. This leads to listeners being notified twice with the same "new" value for example, but with a different old value. Imagine the above listener receives the following change events: > > scene1 becomes scene3 > scene2 becomes scene3 > > The above code would remove its listeners from `scene1` and `scene2`, and register two listeners on `scene3`. This leads to the listener being called twice when something changes. When later the scene changes to `scene4`, it receives: > > scene3 becomes scene4 > > Because it registered its listener twice on `scene3`, and only removes one of them, it now has listeners on both `scene3` and `scene4`. > > Clearly it is incredibly important that changes make sense, or even simple code that looks innocuous becomes problematic. > > # The PR > > The `ListenerManager` differs from `ExpressionHelper` in the following ways: > - Provides correct old/new values to `ChangeListener`s under all circumstances > - Unnecessary change events are never sent > - Single invalidation or change listeners are inlined directly into the observable class (in other words, properties with only a single listener don't take up any extra space at all) > - Performance is slightly worse when calling **change** listeners (but remember that `ExpressionHelper` is not following the contract). > - Removed listeners are never called after being removed (even if they were part of the initial list when the notification triggered) > - Added listeners are only called when a new non-nested (top level) notification starts > - Locking and maintaining the listener list works a bit differently -- the main takeaway is that the list indices remain the same when modified during nested modifications, which allows using the same list no matter how deep the nesting > - No reference is stored to the ObservableValue and no copy is kept of the current value > - Memory use when there is more than 1 listener should be similar, and better when not > - Although complicated, the code is I think much better separated, and more focused on accomplishing a single task: > - `ListenerManager` manages the listener storage in property classes, and the transformation between the listener variants (it either uses listeners directly, or uses a `ListenerList` when there are multiple listeners). > - `ListenerListBase` handles the locking and compacting of its listener lists. > - `ListenerList` which extends `ListenerListBase` is only concerned with the recursion algorithm for notification. > - `ArrayManager` handles resizing and reallocating of arrays. > - There are variants of `ListenerList` and `ListenerManager` which can cache their old values when its not possible to supply these (this has a cost, and is what `ExpressionHelper` does by default). > > The notification mechanism deals with nested notifications by tracking how many listeners were notified already before the nested notification occurs. For example, if 5 listeners were notified, and then listener 5 makes a nested change, then in that nested change only the first 5 listeners are notified again (if they still exist). The nested loop is then terminated early, at which point the top level loop resumes: it continues where it left of and notifies listener 6 and so on. This ensures that all notifications are always correct, and that listeners that "veto" changes can effectively block later listeners from seeing those at all. > > For example, if the first listener always uppercases any received values, then any succeeding listeners will always see only uppercase values. The first listener receives two notifications (`X -> a` and `a -> A`), and the second receives only `X -> A`. Contrast this with the old `ExpressionHelper`, which sends odd notifications to the second listener (`a -> A` and `X -> A`, in that order). > > Unfortunately, due to a somewhat weird design choice in the PropertyBase classes, the strategy of not having to cache the "current value" (or old value) can't be used (it can only be used for Bindings for now). So there is another variant of this helper, called `OldValueCachingListenerHelper`, with some slight differences: > > - Has an extra field for storing the old value when there are any `ChangeListener`s active > - Can't store a `ChangeListener` inline; a minimal wrapper is needed to track the old value (ExpressionHelper does the same) John Hendrikx has updated the pull request incrementally with two additional commits since the last revision: - Improve doc - Move listener call code to ListListenerBase ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1081/files - new: https://git.openjdk.org/jfx/pull/1081/files/89369d3f..997bdcb2 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=03 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=02-03 Stats: 78 lines in 6 files changed: 19 ins; 53 del; 6 mod Patch: https://git.openjdk.org/jfx/pull/1081.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1081/head:pull/1081 PR: https://git.openjdk.org/jfx/pull/1081 From jhendrikx at openjdk.org Sun Apr 16 09:27:47 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 09:27:47 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v5] In-Reply-To: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: > This provides and uses a new implementation of `ExpressionHelper`, called `ListenerManager` with improved semantics. > > # Behavior > > |Listener...|ExpressionHelper|ListenerManager| > |---|---|---| > |Invocation Order|In order they were registered, invalidation listeners always before change listeners|(unchanged)| > |Removal during Notification|All listeners present when notification started are notified, but excluded for any nested changes|Listeners are removed immediately regardless of nesting| > |Addition during Notification|Only listeners present when notification started are notified, but included for any nested changes|New listeners are never called during the current notification regardless of nesting| > > ## Nested notifications: > > | |ExpressionHelper|ListenerManager| > |---|---|---| > |Type|Depth first (call stack increases for each nested level)|(same)| > |# of Calls|Listeners * Depth (using incorrect old values)|Collapses nested changes, skipping non-changes| > |Vetoing Possible?|No|Yes| > |Old Value correctness|Only for listeners called before listeners making nested changes|Always| > > # Performance > > |Listener|ExpressionHelper|ListenerManager| > |---|---|---| > |Addition|Array based, append in empty slot, resize as needed|(same)| > |Removal|Array based, shift array, resize as needed|(same)| > |Addition during notification|Array is copied, removing collected WeakListeneres in the process|Tracked (append at end)| > |Removal during notification|As above|Entry is `null`ed| > |Notification completion with changes|-|Null entries (and collected WeakListeners) are removed| > |Notifying Invalidation Listeners|1 ns each|(same)| > |Notifying Change Listeners|1 ns each (*)|2-3 ns each| > > (*) a simple for loop is close to optimal, but unfortunately does not provide correct old values > > # Memory Use > > Does not include alignment, and assumes a 32-bit VM or one that is using compressed oops. > > |Listener|ExpressionHelper|ListenerManager|OldValueCaching ListenerManager| > |---|---|---|---| > |No Listeners|none|none|none| > |Single InvalidationListener|16 bytes overhead|none|none| > |Single ChangeListener|20 bytes overhead|none|16 bytes overhead| > |Multiple listeners|57 + 4 per listener (excluding unused slots)|57 + 4 per listener (excluding unused slots)|61 + 4 per listener (excluding unused slots)| > > # About nested changes > > Nested changes are simply changes that are made to a property that is currently in the process of notifying its listeners. This all occurs on the same thread, and a nested change is nothing more than the same property being modified, triggering its listeners again deeper in the call stack with another notification, while higher up the call stack a notification is still being handled: > > (top of stack) > fireValueChangedEvent (property A) <-- nested notification > setValue (property A) <-- listener modifies property A > changed (Listener 1) <-- a listener called by original notification > fireValueChangedEvent (property A) <-- original notification > > ## How do nested changes look? > > Let's say we have three listeners, where the middle listener changes values to uppercase. When changing a property with the initial value "A" to a lowercase "b" the listeners would see the following events: > > ### ExpressionHelper > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | | > | 1 |T5 | | |b -> B| | > | 0 |T6 | | |A -> B|Top level loop is resumed| > > Note how the values received by the 3rd listener are non-sensical. It receives two changes both of which changes to B from old values that are out of order. > > ### ListenerManager (new) > This how ListenerManager sends out these events: > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | The nested loop is terminated early at this point | > | 0 |T5 | | |A -> B|Top level loop is resumed| > > Note how the 3rd listener now receives an event that reflects what actually happened from its perspective. Also note that less events overall needed to be send out. > > # About Invocation Order > > A lot of code depends on the fact that an earlier registered listener of the same type is called **before** a later registered later of the same type. For listeners of different types it is a bit less clear. What is clear however is that invalidation and change listeners are defined by separate interfaces. Mixing their invocations (to conserve registration order) would not make sense. Historically, invalidation listeners are called before change listeners. No doubt, code will be (unknowingly) relying on this in today's JavaFX applications so changing this is not recommended. Perhaps there is reason to say that invalidation listeners should be called first as they're defined by the super interface of `ObservableValue` which introduces change listeners. > > # About Listener Add/Remove performance > > Many discussions have happened in the past to improve the performance of removing listeners, ranging from using maps to ordered data structures with better remove performance. Often these solutions would subtly change the notification order, or increase the overhead per listener significantly. > > But these discussions never really looked at the other consequences of having tens of thousands of listeners. Even if listeners could be removed in something approaching O(1) time (additions are already O(1) and so are not the issue), what about the performance of notifying that many listeners? That will still be O(n), and so even if JavaFX could handle addition and removal of that many listeners comfortably, actually using a property with that many listeners is still impossible as it would block the FX thread for far too long when sending out that many notifications. > > Therefore, I'm of the opinion that "fixing" this "problem" is pointless. Instead, having that many listeners should be considered a design flaw in the application. A solution that registers only a single listener that updates a shared model may be much more appropriate. > > # About Old Value Correctness > ...and why it is important. > > A change listener provides a callback that gives the old and the new value. One may reasonably expect that these values are never the same, and one may reasonably expect that the given old value is the same as the previous invocation's new value (if there was a previous invocation). > > In JavaFX, many change listeners are used for important tasks, ranging from reverting changes in order to veto something, to registering and unregistering listeners on properties. Many of those change listeners do not care about the old value, but there are a significant number that use it and rely on it being correct. A common example is the registering of a listener on the "new" value, and removing the same listener from the "old" value in order to maintain a link to some other property that changes location: > > (obs, old, current) -> { > if (old != null) { > old.removeListener(x); > } > if (current != null) { > current.addListener(x); > } > } > > The above code looks bug free, and it would be if the provided old values are always correct. Unfortunately, this does not have to be the case. When a nested change is made (which can be made by a user registered listener on the same property), `ExpressionHelper` makes no effort to ensure that for all registered listener the received old and new values make sense. This leads to listeners being notified twice with the same "new" value for example, but with a different old value. Imagine the above listener receives the following change events: > > scene1 becomes scene3 > scene2 becomes scene3 > > The above code would remove its listeners from `scene1` and `scene2`, and register two listeners on `scene3`. This leads to the listener being called twice when something changes. When later the scene changes to `scene4`, it receives: > > scene3 becomes scene4 > > Because it registered its listener twice on `scene3`, and only removes one of them, it now has listeners on both `scene3` and `scene4`. > > Clearly it is incredibly important that changes make sense, or even simple code that looks innocuous becomes problematic. > > # The PR > > The `ListenerManager` differs from `ExpressionHelper` in the following ways: > - Provides correct old/new values to `ChangeListener`s under all circumstances > - Unnecessary change events are never sent > - Single invalidation or change listeners are inlined directly into the observable class (in other words, properties with only a single listener don't take up any extra space at all) > - Performance is slightly worse when calling **change** listeners (but remember that `ExpressionHelper` is not following the contract). > - Removed listeners are never called after being removed (even if they were part of the initial list when the notification triggered) > - Added listeners are only called when a new non-nested (top level) notification starts > - Locking and maintaining the listener list works a bit differently -- the main takeaway is that the list indices remain the same when modified during nested modifications, which allows using the same list no matter how deep the nesting > - No reference is stored to the ObservableValue and no copy is kept of the current value > - Memory use when there is more than 1 listener should be similar, and better when not > - Although complicated, the code is I think much better separated, and more focused on accomplishing a single task: > - `ListenerManager` manages the listener storage in property classes, and the transformation between the listener variants (it either uses listeners directly, or uses a `ListenerList` when there are multiple listeners). > - `ListenerListBase` handles the locking and compacting of its listener lists. > - `ListenerList` which extends `ListenerListBase` is only concerned with the recursion algorithm for notification. > - `ArrayManager` handles resizing and reallocating of arrays. > - There are variants of `ListenerList` and `ListenerManager` which can cache their old values when its not possible to supply these (this has a cost, and is what `ExpressionHelper` does by default). > > The notification mechanism deals with nested notifications by tracking how many listeners were notified already before the nested notification occurs. For example, if 5 listeners were notified, and then listener 5 makes a nested change, then in that nested change only the first 5 listeners are notified again (if they still exist). The nested loop is then terminated early, at which point the top level loop resumes: it continues where it left of and notifies listener 6 and so on. This ensures that all notifications are always correct, and that listeners that "veto" changes can effectively block later listeners from seeing those at all. > > For example, if the first listener always uppercases any received values, then any succeeding listeners will always see only uppercase values. The first listener receives two notifications (`X -> a` and `a -> A`), and the second receives only `X -> A`. Contrast this with the old `ExpressionHelper`, which sends odd notifications to the second listener (`a -> A` and `X -> A`, in that order). > > Unfortunately, due to a somewhat weird design choice in the PropertyBase classes, the strategy of not having to cache the "current value" (or old value) can't be used (it can only be used for Bindings for now). So there is another variant of this helper, called `OldValueCachingListenerHelper`, with some slight differences: > > - Has an extra field for storing the old value when there are any `ChangeListener`s active > - Can't store a `ChangeListener` inline; a minimal wrapper is needed to track the old value (ExpressionHelper does the same) John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Small bug fix in OldValueCachingListenerList - Added a test case to detect and avoid this problem ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1081/files - new: https://git.openjdk.org/jfx/pull/1081/files/997bdcb2..42729644 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=04 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=03-04 Stats: 84 lines in 2 files changed: 81 ins; 1 del; 2 mod Patch: https://git.openjdk.org/jfx/pull/1081.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1081/head:pull/1081 PR: https://git.openjdk.org/jfx/pull/1081 From jhendrikx at openjdk.org Sun Apr 16 12:34:43 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 12:34:43 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v6] In-Reply-To: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: > This provides and uses a new implementation of `ExpressionHelper`, called `ListenerManager` with improved semantics. > > # Behavior > > |Listener...|ExpressionHelper|ListenerManager| > |---|---|---| > |Invocation Order|In order they were registered, invalidation listeners always before change listeners|(unchanged)| > |Removal during Notification|All listeners present when notification started are notified, but excluded for any nested changes|Listeners are removed immediately regardless of nesting| > |Addition during Notification|Only listeners present when notification started are notified, but included for any nested changes|New listeners are never called during the current notification regardless of nesting| > > ## Nested notifications: > > | |ExpressionHelper|ListenerManager| > |---|---|---| > |Type|Depth first (call stack increases for each nested level)|(same)| > |# of Calls|Listeners * Depth (using incorrect old values)|Collapses nested changes, skipping non-changes| > |Vetoing Possible?|No|Yes| > |Old Value correctness|Only for listeners called before listeners making nested changes|Always| > > # Performance > > |Listener|ExpressionHelper|ListenerManager| > |---|---|---| > |Addition|Array based, append in empty slot, resize as needed|(same)| > |Removal|Array based, shift array, resize as needed|(same)| > |Addition during notification|Array is copied, removing collected WeakListeneres in the process|Tracked (append at end)| > |Removal during notification|As above|Entry is `null`ed| > |Notification completion with changes|-|Null entries (and collected WeakListeners) are removed| > |Notifying Invalidation Listeners|1 ns each|(same)| > |Notifying Change Listeners|1 ns each (*)|2-3 ns each| > > (*) a simple for loop is close to optimal, but unfortunately does not provide correct old values > > # Memory Use > > Does not include alignment, and assumes a 32-bit VM or one that is using compressed oops. > > |Listener|ExpressionHelper|ListenerManager|OldValueCaching ListenerManager| > |---|---|---|---| > |No Listeners|none|none|none| > |Single InvalidationListener|16 bytes overhead|none|none| > |Single ChangeListener|20 bytes overhead|none|16 bytes overhead| > |Multiple listeners|57 + 4 per listener (excluding unused slots)|57 + 4 per listener (excluding unused slots)|61 + 4 per listener (excluding unused slots)| > > # About nested changes > > Nested changes are simply changes that are made to a property that is currently in the process of notifying its listeners. This all occurs on the same thread, and a nested change is nothing more than the same property being modified, triggering its listeners again deeper in the call stack with another notification, while higher up the call stack a notification is still being handled: > > (top of stack) > fireValueChangedEvent (property A) <-- nested notification > setValue (property A) <-- listener modifies property A > changed (Listener 1) <-- a listener called by original notification > fireValueChangedEvent (property A) <-- original notification > > ## How do nested changes look? > > Let's say we have three listeners, where the middle listener changes values to uppercase. When changing a property with the initial value "A" to a lowercase "b" the listeners would see the following events: > > ### ExpressionHelper > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | | > | 1 |T5 | | |b -> B| | > | 0 |T6 | | |A -> B|Top level loop is resumed| > > Note how the values received by the 3rd listener are non-sensical. It receives two changes both of which changes to B from old values that are out of order. > > ### ListenerManager (new) > This how ListenerManager sends out these events: > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | The nested loop is terminated early at this point | > | 0 |T5 | | |A -> B|Top level loop is resumed| > > Note how the 3rd listener now receives an event that reflects what actually happened from its perspective. Also note that less events overall needed to be send out. > > # About Invocation Order > > A lot of code depends on the fact that an earlier registered listener of the same type is called **before** a later registered later of the same type. For listeners of different types it is a bit less clear. What is clear however is that invalidation and change listeners are defined by separate interfaces. Mixing their invocations (to conserve registration order) would not make sense. Historically, invalidation listeners are called before change listeners. No doubt, code will be (unknowingly) relying on this in today's JavaFX applications so changing this is not recommended. Perhaps there is reason to say that invalidation listeners should be called first as they're defined by the super interface of `ObservableValue` which introduces change listeners. > > # About Listener Add/Remove performance > > Many discussions have happened in the past to improve the performance of removing listeners, ranging from using maps to ordered data structures with better remove performance. Often these solutions would subtly change the notification order, or increase the overhead per listener significantly. > > But these discussions never really looked at the other consequences of having tens of thousands of listeners. Even if listeners could be removed in something approaching O(1) time (additions are already O(1) and so are not the issue), what about the performance of notifying that many listeners? That will still be O(n), and so even if JavaFX could handle addition and removal of that many listeners comfortably, actually using a property with that many listeners is still impossible as it would block the FX thread for far too long when sending out that many notifications. > > Therefore, I'm of the opinion that "fixing" this "problem" is pointless. Instead, having that many listeners should be considered a design flaw in the application. A solution that registers only a single listener that updates a shared model may be much more appropriate. > > # About Old Value Correctness > ...and why it is important. > > A change listener provides a callback that gives the old and the new value. One may reasonably expect that these values are never the same, and one may reasonably expect that the given old value is the same as the previous invocation's new value (if there was a previous invocation). > > In JavaFX, many change listeners are used for important tasks, ranging from reverting changes in order to veto something, to registering and unregistering listeners on properties. Many of those change listeners do not care about the old value, but there are a significant number that use it and rely on it being correct. A common example is the registering of a listener on the "new" value, and removing the same listener from the "old" value in order to maintain a link to some other property that changes location: > > (obs, old, current) -> { > if (old != null) { > old.removeListener(x); > } > if (current != null) { > current.addListener(x); > } > } > > The above code looks bug free, and it would be if the provided old values are always correct. Unfortunately, this does not have to be the case. When a nested change is made (which can be made by a user registered listener on the same property), `ExpressionHelper` makes no effort to ensure that for all registered listener the received old and new values make sense. This leads to listeners being notified twice with the same "new" value for example, but with a different old value. Imagine the above listener receives the following change events: > > scene1 becomes scene3 > scene2 becomes scene3 > > The above code would remove its listeners from `scene1` and `scene2`, and register two listeners on `scene3`. This leads to the listener being called twice when something changes. When later the scene changes to `scene4`, it receives: > > scene3 becomes scene4 > > Because it registered its listener twice on `scene3`, and only removes one of them, it now has listeners on both `scene3` and `scene4`. > > Clearly it is incredibly important that changes make sense, or even simple code that looks innocuous becomes problematic. > > # The PR > > The `ListenerManager` differs from `ExpressionHelper` in the following ways: > - Provides correct old/new values to `ChangeListener`s under all circumstances > - Unnecessary change events are never sent > - Single invalidation or change listeners are inlined directly into the observable class (in other words, properties with only a single listener don't take up any extra space at all) > - Performance is slightly worse when calling **change** listeners (but remember that `ExpressionHelper` is not following the contract). > - Removed listeners are never called after being removed (even if they were part of the initial list when the notification triggered) > - Added listeners are only called when a new non-nested (top level) notification starts > - Locking and maintaining the listener list works a bit differently -- the main takeaway is that the list indices remain the same when modified during nested modifications, which allows using the same list no matter how deep the nesting > - No reference is stored to the ObservableValue and no copy is kept of the current value > - Memory use when there is more than 1 listener should be similar, and better when not > - Although complicated, the code is I think much better separated, and more focused on accomplishing a single task: > - `ListenerManager` manages the listener storage in property classes, and the transformation between the listener variants (it either uses listeners directly, or uses a `ListenerList` when there are multiple listeners). > - `ListenerListBase` handles the locking and compacting of its listener lists. > - `ListenerList` which extends `ListenerListBase` is only concerned with the recursion algorithm for notification. > - `ArrayManager` handles resizing and reallocating of arrays. > - There are variants of `ListenerList` and `ListenerManager` which can cache their old values when its not possible to supply these (this has a cost, and is what `ExpressionHelper` does by default). > > The notification mechanism deals with nested notifications by tracking how many listeners were notified already before the nested notification occurs. For example, if 5 listeners were notified, and then listener 5 makes a nested change, then in that nested change only the first 5 listeners are notified again (if they still exist). The nested loop is then terminated early, at which point the top level loop resumes: it continues where it left of and notifies listener 6 and so on. This ensures that all notifications are always correct, and that listeners that "veto" changes can effectively block later listeners from seeing those at all. > > For example, if the first listener always uppercases any received values, then any succeeding listeners will always see only uppercase values. The first listener receives two notifications (`X -> a` and `a -> A`), and the second receives only `X -> A`. Contrast this with the old `ExpressionHelper`, which sends odd notifications to the second listener (`a -> A` and `X -> A`, in that order). > > Unfortunately, due to a somewhat weird design choice in the PropertyBase classes, the strategy of not having to cache the "current value" (or old value) can't be used (it can only be used for Bindings for now). So there is another variant of this helper, called `OldValueCachingListenerHelper`, with some slight differences: > > - Has an extra field for storing the old value when there are any `ChangeListener`s active > - Can't store a `ChangeListener` inline; a minimal wrapper is needed to track the old value (ExpressionHelper does the same) John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Merge the recursive notification loop code Made loop in ListenerList slightly more generic to allow merging the logic in OldValueCachingListenerList and ListenerList; performance impact seems minimal ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1081/files - new: https://git.openjdk.org/jfx/pull/1081/files/42729644..c86cab5d Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=05 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=04-05 Stats: 91 lines in 4 files changed: 6 ins; 76 del; 9 mod Patch: https://git.openjdk.org/jfx/pull/1081.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1081/head:pull/1081 PR: https://git.openjdk.org/jfx/pull/1081 From jhendrikx at openjdk.org Sun Apr 16 12:37:45 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 12:37:45 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v6] In-Reply-To: References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: On Sun, 16 Apr 2023 07:43:05 GMT, John Hendrikx wrote: >> modules/javafx.base/src/main/java/com/sun/javafx/binding/OldValueCachingListenerList.java line 101: >> >>> 99: * notification otherwise {@code false} >>> 100: */ >>> 101: public boolean notifyListeners(ObservableValue observableValue) { >> >> The code in this method is _almost_ identical to `ListenerList.notifyListeners(ObservableValue, T)`. >> Given that this method is somewhat complex, I think it would be good to use a common implementation. >> This will help with code review, and decrease the chance that both methods diverge further with future modifications. > > I agree with you there, and I've been looking what would be a good way to achieve this. I will take another look soon. My primary concern is that this is a somewhat critical path, and I would want to ensure that it doesn't cause too much performance regressions (I've already been optimizing all of this code with the help of a JMH test) While looking that code over to see if it could be merged without impacting the general case, I discovered a small bug in the OldValueCaching version. After I fixed it, the code was even more similar than it was already. The only different still is the fact that the latest value must be kept track of whenever ObservableValue#getValue is called. I've now added an extra parameter to the generic version to allow for storing the latest value when it is queried (and not storing it if it's not needed). This seems to have a minimal performance impact only, so I think the trade off is acceptable. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167895136 From mstrauss at openjdk.org Sun Apr 16 17:22:39 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Sun, 16 Apr 2023 17:22:39 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v6] In-Reply-To: References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: <7AQ0bfREYbXW3bhhBpoE5m3b1LcGdgIhPfqr9-Wx5bo=.ef24ec63-5ed7-458f-bd0a-6f089b3b4f21@github.com> On Sun, 16 Apr 2023 12:34:44 GMT, John Hendrikx wrote: >> I agree with you there, and I've been looking what would be a good way to achieve this. I will take another look soon. My primary concern is that this is a somewhat critical path, and I would want to ensure that it doesn't cause too much performance regressions (I've already been optimizing all of this code with the help of a JMH test) > > While looking that code over to see if it could be merged without impacting the general case, I discovered a small bug in the OldValueCaching version. After I fixed it, the code was even more similar than it was already. The only different still is the fact that the latest value must be kept track of whenever ObservableValue#getValue is called. > > I've now added an extra parameter to the generic version to allow for storing the latest value when it is queried (and not storing it if it's not needed). This seems to have a minimal performance impact only, so I think the trade off is acceptable. Have you considered adding a method like `void valueUpdated(T value) {}` to `ListenerList`? This will require `ListenerList` to have a type variable `T` (which `OldValueCachingListenerList` adds anyway). This method could then be called instead of `latestValueTracker.accept(newValue)`, and `OldValueCachingListenerList` can override it and store the value. The advantage of that would be that we don't need the `latestValueTracker` field. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167979736 From jhendrikx at openjdk.org Sun Apr 16 17:33:42 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 17:33:42 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v6] In-Reply-To: <7AQ0bfREYbXW3bhhBpoE5m3b1LcGdgIhPfqr9-Wx5bo=.ef24ec63-5ed7-458f-bd0a-6f089b3b4f21@github.com> References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> <7AQ0bfREYbXW3bhhBpoE5m3b1LcGdgIhPfqr9-Wx5bo=.ef24ec63-5ed7-458f-bd0a-6f089b3b4f21@github.com> Message-ID: On Sun, 16 Apr 2023 17:20:08 GMT, Michael Strau? wrote: >> While looking that code over to see if it could be merged without impacting the general case, I discovered a small bug in the OldValueCaching version. After I fixed it, the code was even more similar than it was already. The only different still is the fact that the latest value must be kept track of whenever ObservableValue#getValue is called. >> >> I've now added an extra parameter to the generic version to allow for storing the latest value when it is queried (and not storing it if it's not needed). This seems to have a minimal performance impact only, so I think the trade off is acceptable. > > Have you considered adding a method like `void valueUpdated(T value) {}` to `ListenerList`? This will require `ListenerList` to have a type variable `T` (which `OldValueCachingListenerList` adds anyway). > > This method could then be called instead of `latestValueTracker.accept(newValue)`, and `OldValueCachingListenerList` can override it and store the value. The advantage of that would be that we don't need the `latestValueTracker` field. Yeah, I'll test that out, it's better not to have that extra field in that class. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1081#discussion_r1167981446 From jhendrikx at openjdk.org Sun Apr 16 19:51:42 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Sun, 16 Apr 2023 19:51:42 GMT Subject: RFR: 8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v6] In-Reply-To: References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: <9AkS8BwqBtz0zusSbwZSPehjIxq0YgkpLudQGw96DEU=.2a97906a-3248-452c-a13c-6da6e99cdb10@github.com> On Sun, 16 Apr 2023 12:34:43 GMT, John Hendrikx wrote: >> This provides and uses a new implementation of `ExpressionHelper`, called `ListenerManager` with improved semantics. >> >> # Behavior >> >> |Listener...|ExpressionHelper|ListenerManager| >> |---|---|---| >> |Invocation Order|In order they were registered, invalidation listeners always before change listeners|(unchanged)| >> |Removal during Notification|All listeners present when notification started are notified, but excluded for any nested changes|Listeners are removed immediately regardless of nesting| >> |Addition during Notification|Only listeners present when notification started are notified, but included for any nested changes|New listeners are never called during the current notification regardless of nesting| >> >> ## Nested notifications: >> >> | |ExpressionHelper|ListenerManager| >> |---|---|---| >> |Type|Depth first (call stack increases for each nested level)|(same)| >> |# of Calls|Listeners * Depth (using incorrect old values)|Collapses nested changes, skipping non-changes| >> |Vetoing Possible?|No|Yes| >> |Old Value correctness|Only for listeners called before listeners making nested changes|Always| >> >> # Performance >> >> |Listener|ExpressionHelper|ListenerManager| >> |---|---|---| >> |Addition|Array based, append in empty slot, resize as needed|(same)| >> |Removal|Array based, shift array, resize as needed|(same)| >> |Addition during notification|Array is copied, removing collected WeakListeneres in the process|Tracked (append at end)| >> |Removal during notification|As above|Entry is `null`ed| >> |Notification completion with changes|-|Null entries (and collected WeakListeners) are removed| >> |Notifying Invalidation Listeners|1 ns each|(same)| >> |Notifying Change Listeners|1 ns each (*)|2-3 ns each| >> >> (*) a simple for loop is close to optimal, but unfortunately does not provide correct old values >> >> # Memory Use >> >> Does not include alignment, and assumes a 32-bit VM or one that is using compressed oops. >> >> |Listener|ExpressionHelper|ListenerManager|OldValueCaching ListenerManager| >> |---|---|---|---| >> |No Listeners|none|none|none| >> |Single InvalidationListener|16 bytes overhead|none|none| >> |Single ChangeListener|20 bytes overhead|none|16 bytes overhead| >> |Multiple listeners|57 + 4 per listener (excluding unused slots)|57 + 4 per listener (excluding unused slots)|61 + 4 per listener (excluding unused slots)| >> >> # About nested changes >> >> Nested changes are simply changes that are made to a property that is currently in the process of notifying its listeners. This all occurs on the same thread, and a nested change is nothing more than the same property being modified, triggering its listeners again deeper in the call stack with another notification, while higher up the call stack a notification is still being handled: >> >> (top of stack) >> fireValueChangedEvent (property A) <-- nested notification >> setValue (property A) <-- listener modifies property A >> changed (Listener 1) <-- a listener called by original notification >> fireValueChangedEvent (property A) <-- original notification >> >> ## How do nested changes look? >> >> Let's say we have three listeners, where the middle listener changes values to uppercase. When changing a property with the initial value "A" to a lowercase "b" the listeners would see the following events: >> >> ### ExpressionHelper >> |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| >> |---|---|---|---|---|---| >> | 0 |T1 |A -> b| | | | >> | 0 |T2 | |A -> b| |Value is changed to B| >> | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | >> | 1 |T4 | |b -> B| | | >> | 1 |T5 | | |b -> B| | >> | 0 |T6 | | |A -> B|Top level loop is resumed| >> >> Note how the values received by the 3rd listener are non-sensical. It receives two changes both of which changes to B from old values that are out of order. >> >> ### ListenerManager (new) >> This how ListenerManager sends out these events: >> |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| >> |---|---|---|---|---|---| >> | 0 |T1 |A -> b| | | | >> | 0 |T2 | |A -> b| |Value is changed to B| >> | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | >> | 1 |T4 | |b -> B| | The nested loop is terminated early at this point | >> | 0 |T5 | | |A -> B|Top level loop is resumed| >> >> Note how the 3rd listener now receives an event that reflects what actually happened from its perspective. Also note that less events overall needed to be send out. >> >> # About Invocation Order >> >> A lot of code depends on the fact that an earlier registered listener of the same type is called **before** a later registered later of the same type. For listeners of different types it is a bit less clear. What is clear however is that invalidation and change listeners are defined by separate interfaces. Mixing their invocations (to conserve registration order) would not make sense. Historically, invalidation listeners are called before change listeners. No doubt, code will be (unknowingly) relying on this in today's JavaFX applications so changing this is not recommended. Perhaps there is reason to say that invalidation listeners should be called first as they're defined by the super interface of `ObservableValue` which introduces change listeners. >> >> # About Listener Add/Remove performance >> >> Many discussions have happened in the past to improve the performance of removing listeners, ranging from using maps to ordered data structures with better remove performance. Often these solutions would subtly change the notification order, or increase the overhead per listener significantly. >> >> But these discussions never really looked at the other consequences of having tens of thousands of listeners. Even if listeners could be removed in something approaching O(1) time (additions are already O(1) and so are not the issue), what about the performance of notifying that many listeners? That will still be O(n), and so even if JavaFX could handle addition and removal of that many listeners comfortably, actually using a property with that many listeners is still impossible as it would block the FX thread for far too long when sending out that many notifications. >> >> Therefore, I'm of the opinion that "fixing" this "problem" is pointless. Instead, having that many listeners should be considered a design flaw in the application. A solution that registers only a single listener that updates a shared model may be much more appropriate. >> >> # About Old Value Correctness >> ...and why it is important. >> >> A change listener provides a callback that gives the old and the new value. One may reasonably expect that these values are never the same, and one may reasonably expect that the given old value is the same as the previous invocation's new value (if there was a previous invocation). >> >> In JavaFX, many change listeners are used for important tasks, ranging from reverting changes in order to veto something, to registering and unregistering listeners on properties. Many of those change listeners do not care about the old value, but there are a significant number that use it and rely on it being correct. A common example is the registering of a listener on the "new" value, and removing the same listener from the "old" value in order to maintain a link to some other property that changes location: >> >> (obs, old, current) -> { >> if (old != null) { >> old.removeListener(x); >> } >> if (current != null) { >> current.addListener(x); >> } >> } >> >> The above code looks bug free, and it would be if the provided old values are always correct. Unfortunately, this does not have to be the case. When a nested change is made (which can be made by a user registered listener on the same property), `ExpressionHelper` makes no effort to ensure that for all registered listener the received old and new values make sense. This leads to listeners being notified twice with the same "new" value for example, but with a different old value. Imagine the above listener receives the following change events: >> >> scene1 becomes scene3 >> scene2 becomes scene3 >> >> The above code would remove its listeners from `scene1` and `scene2`, and register two listeners on `scene3`. This leads to the listener being called twice when something changes. When later the scene changes to `scene4`, it receives: >> >> scene3 becomes scene4 >> >> Because it registered its listener twice on `scene3`, and only removes one of them, it now has listeners on both `scene3` and `scene4`. >> >> Clearly it is incredibly important that changes make sense, or even simple code that looks innocuous becomes problematic. >> >> # The PR >> >> The `ListenerManager` differs from `ExpressionHelper` in the following ways: >> - Provides correct old/new values to `ChangeListener`s under all circumstances >> - Unnecessary change events are never sent >> - Single invalidation or change listeners are inlined directly into the observable class (in other words, properties with only a single listener don't take up any extra space at all) >> - Performance is slightly worse when calling **change** listeners (but remember that `ExpressionHelper` is not following the contract). >> - Removed listeners are never called after being removed (even if they were part of the initial list when the notification triggered) >> - Added listeners are only called when a new non-nested (top level) notification starts >> - Locking and maintaining the listener list works a bit differently -- the main takeaway is that the list indices remain the same when modified during nested modifications, which allows using the same list no matter how deep the nesting >> - No reference is stored to the ObservableValue and no copy is kept of the current value >> - Memory use when there is more than 1 listener should be similar, and better when not >> - Although complicated, the code is I think much better separated, and more focused on accomplishing a single task: >> - `ListenerManager` manages the listener storage in property classes, and the transformation between the listener variants (it either uses listeners directly, or uses a `ListenerList` when there are multiple listeners). >> - `ListenerListBase` handles the locking and compacting of its listener lists. >> - `ListenerList` which extends `ListenerListBase` is only concerned with the recursion algorithm for notification. >> - `ArrayManager` handles resizing and reallocating of arrays. >> - There are variants of `ListenerList` and `ListenerManager` which can cache their old values when its not possible to supply these (this has a cost, and is what `ExpressionHelper` does by default). >> >> The notification mechanism deals with nested notifications by tracking how many listeners were notified already before the nested notification occurs. For example, if 5 listeners were notified, and then listener 5 makes a nested change, then in that nested change only the first 5 listeners are notified again (if they still exist). The nested loop is then terminated early, at which point the top level loop resumes: it continues where it left of and notifies listener 6 and so on. This ensures that all notifications are always correct, and that listeners that "veto" changes can effectively block later listeners from seeing those at all. >> >> For example, if the first listener always uppercases any received values, then any succeeding listeners will always see only uppercase values. The first listener receives two notifications (`X -> a` and `a -> A`), and the second receives only `X -> A`. Contrast this with the old `ExpressionHelper`, which sends odd notifications to the second listener (`a -> A` and `X -> A`, in that order). >> >> Unfortunately, due to a somewhat weird design choice in the PropertyBase classes, the strategy of not having to cache the "current value" (or old value) can't be used (it can only be used for Bindings for now). So there is another variant of this helper, called `OldValueCachingListenerHelper`, with some slight differences: >> >> - Has an extra field for storing the old value when there are any `ChangeListener`s active >> - Can't store a `ChangeListener` inline; a minimal wrapper is needed to track the old value (ExpressionHelper does the same) > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Merge the recursive notification loop code > > Made loop in ListenerList slightly more generic to allow merging the > logic in OldValueCachingListenerList and ListenerList; performance > impact seems minimal # Benchmarks Here are are some performance tests. The main take away is that invalidation performs roughly the same as before, while change listener notifications, which have acquired some more complexity, are about twice as slow. Also worth nothing is that the methods timed are generally so fast that a branch mispredication can have a big impact on the absolute performance. For example, when I re-order the method that "switches" on the data type (ListenerList, InvalidationListener or ChangeListener) I can get slightly better performance for some of these, losing performance somewhere else. I've picked a balance for now that makes the code easiest to read. The branch mispredication is also the reason that a single `ChangeListener` performs about as good as a `ListenerList` with up to 3 listeners (but of course, the single listener case consumes less memory). ExpressionHelper ListenerManager Benchmark (inv_chg_ListenerCounts) Mode Cnt Score Error Units Score Error Units FireValueChanged.binding 0, 0 avgt 10 2.247 ? 0.022 ns/op 2.335 ? 0.021 ns/op FireValueChanged.binding 0, 1 avgt 10 8.858 ? 0.136 ns/op 17.715 ? 0.092 ns/op FireValueChanged.binding 1, 0 avgt 10 2.551 ? 0.080 ns/op 2.267 ? 0.028 ns/op FireValueChanged.binding 0, 2 avgt 10 10.278 ? 0.148 ns/op 12.049 ? 0.103 ns/op FireValueChanged.binding 2, 0 avgt 10 4.831 ? 0.064 ns/op 5.560 ? 0.104 ns/op FireValueChanged.binding 2, 2 avgt 10 11.517 ? 0.114 ns/op 14.409 ? 0.511 ns/op FireValueChanged.binding 0, 3 avgt 10 11.301 ? 0.096 ns/op 13.756 ? 0.308 ns/op FireValueChanged.binding 3, 0 avgt 10 6.411 ? 0.246 ns/op 6.822 ? 0.105 ns/op FireValueChanged.binding 3, 3 avgt 10 13.410 ? 0.151 ns/op 16.564 ? 0.305 ns/op FireValueChanged.binding 0, 20 avgt 10 17.952 ? 0.182 ns/op 36.591 ? 0.344 ns/op FireValueChanged.binding 20, 0 avgt 10 11.817 ? 0.105 ns/op 12.869 ? 0.115 ns/op FireValueChanged.binding 20, 20 avgt 10 26.356 ? 0.344 ns/op 50.574 ? 2.497 ns/op FireValueChanged.longBinding 0, 0 avgt 10 1.337 ? 0.029 ns/op 2.221 ? 0.022 ns/op FireValueChanged.longBinding 0, 1 avgt 10 5.707 ? 0.084 ns/op 14.803 ? 0.051 ns/op FireValueChanged.longBinding 1, 0 avgt 10 1.408 ? 0.011 ns/op 2.355 ? 0.029 ns/op FireValueChanged.longBinding 0, 2 avgt 10 7.890 ? 0.080 ns/op 13.723 ? 0.329 ns/op FireValueChanged.longBinding 2, 0 avgt 10 4.082 ? 0.054 ns/op 5.419 ? 0.107 ns/op FireValueChanged.longBinding 2, 2 avgt 10 8.306 ? 0.133 ns/op 13.915 ? 0.206 ns/op FireValueChanged.longBinding 0, 3 avgt 10 8.695 ? 0.118 ns/op 16.345 ? 0.172 ns/op FireValueChanged.longBinding 3, 0 avgt 10 4.379 ? 0.063 ns/op 6.642 ? 0.155 ns/op FireValueChanged.longBinding 3, 3 avgt 10 10.434 ? 0.242 ns/op 16.890 ? 0.188 ns/op FireValueChanged.longBinding 0, 20 avgt 10 14.948 ? 0.172 ns/op 57.031 ? 0.631 ns/op FireValueChanged.longBinding 20, 0 avgt 10 11.345 ? 0.106 ns/op 12.995 ? 0.162 ns/op FireValueChanged.longBinding 20, 20 avgt 10 24.327 ? 0.606 ns/op 64.793 ? 0.903 ns/op FireValueChanged.property 0, 0 avgt 10 3.645 ? 0.101 ns/op 3.654 ? 0.053 ns/op FireValueChanged.property 0, 1 avgt 10 8.631 ? 0.131 ns/op 19.572 ? 0.224 ns/op FireValueChanged.property 1, 0 avgt 10 4.208 ? 0.041 ns/op 3.742 ? 0.066 ns/op FireValueChanged.property 0, 2 avgt 10 11.540 ? 0.345 ns/op 15.681 ? 0.240 ns/op FireValueChanged.property 2, 0 avgt 10 6.447 ? 0.231 ns/op 7.544 ? 0.165 ns/op FireValueChanged.property 2, 2 avgt 10 13.335 ? 0.267 ns/op 15.447 ? 0.365 ns/op FireValueChanged.property 0, 3 avgt 10 12.325 ? 0.237 ns/op 17.656 ? 0.488 ns/op FireValueChanged.property 3, 0 avgt 10 7.334 ? 0.087 ns/op 8.295 ? 0.151 ns/op FireValueChanged.property 3, 3 avgt 10 15.640 ? 0.264 ns/op 18.467 ? 0.489 ns/op FireValueChanged.property 0, 20 avgt 10 18.696 ? 0.346 ns/op 51.939 ? 0.965 ns/op FireValueChanged.property 20, 0 avgt 10 13.002 ? 0.163 ns/op 14.507 ? 0.334 ns/op FireValueChanged.property 20, 20 avgt 10 27.254 ? 0.328 ns/op 48.335 ? 0.916 ns/op ------------- PR Comment: https://git.openjdk.org/jfx/pull/1081#issuecomment-1510471173 From nlisker at openjdk.org Mon Apr 17 03:42:45 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Mon, 17 Apr 2023 03:42:45 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v2] In-Reply-To: <0ZqMcHZ78UF04XZFUQ6H1yv016hFX_E9XvThZtAIwB8=.5822a500-5872-46a9-a315-8a4a509a91c7@github.com> References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> <0ZqMcHZ78UF04XZFUQ6H1yv016hFX_E9XvThZtAIwB8=.5822a500-5872-46a9-a315-8a4a509a91c7@github.com> Message-ID: On Sat, 15 Apr 2023 18:01:28 GMT, Michael Strau? wrote: >> This PR adds the following methods to the `EventTarget` interface: >> 1. `addEventHandler` >> 2. `removeEventHandler` >> 3. `addEventFilter` >> 4. `removeEventFilter` > > Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: > > revert a change in Menu Looks good overall. modules/javafx.base/src/main/java/javafx/event/EventTarget.java line 79: > 77: *

> 78: * It is possible to register a single {@link EventHandler} instance for different event types, > 79: * so the caller needs to specify the event type from which the handler should be unregistered. I would rephrase to "Since it is possible to..., the caller needs to..." Same for filter. modules/javafx.base/src/main/java/javafx/event/EventTarget.java line 95: > 93: * Registers an event filter for this target. > 94: *

> 95: * The filter is called when the node receives an {@link Event} of the specified node -> target modules/javafx.controls/src/main/java/javafx/scene/control/TableColumnBase.java line 737: > 735: * {@inheritDoc} > 736: *

> 737: * The {@code TableColumnBase} class allows registration of listeners which will be notified when editing occurs. The edit events are defined only in the subclasses. Either, if possible, move the events to this class, or clarify that these events are defined in subclasses. `TreeItem` talks more about this - using the cell. modules/javafx.controls/src/main/java/javafx/scene/control/TableColumnBase.java line 738: > 736: *

> 737: * The {@code TableColumnBase} class allows registration of listeners which will be notified when editing occurs. > 738: * Note that {@code TableColumnBase} is not a {@link Node}, and therefore no visual events will be fired on it. Isn't this true for the other classes here as well, like `Tab`? Might it be worth saying this in the other classes too then, or even on `EventTarget` itself (something like "Note that implementing classes that are not a `Node` don't receive visual events")? I would also give an example or 2 of what "visual events" are since this term is not defined anywhere that I know of. ------------- PR Review: https://git.openjdk.org/jfx/pull/1090#pullrequestreview-1387150109 PR Review Comment: https://git.openjdk.org/jfx/pull/1090#discussion_r1168092516 PR Review Comment: https://git.openjdk.org/jfx/pull/1090#discussion_r1168092983 PR Review Comment: https://git.openjdk.org/jfx/pull/1090#discussion_r1168115120 PR Review Comment: https://git.openjdk.org/jfx/pull/1090#discussion_r1168115726 From mstrauss at openjdk.org Mon Apr 17 04:47:24 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 17 Apr 2023 04:47:24 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v3] In-Reply-To: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> Message-ID: <0Wfc0bXGfT31Op1kr9P1GvBFFeWWHuvr0gLJlP3WOU8=.a7496266-eed0-41a7-abbf-4e1930de1401@github.com> > This PR adds the following methods to the `EventTarget` interface: > 1. `addEventHandler` > 2. `removeEventHandler` > 3. `addEventFilter` > 4. `removeEventFilter` Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: doc changes ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1090/files - new: https://git.openjdk.org/jfx/pull/1090/files/7db7f79a..cec4b90b Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1090&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1090&range=01-02 Stats: 5 lines in 1 file changed: 0 ins; 0 del; 5 mod Patch: https://git.openjdk.org/jfx/pull/1090.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1090/head:pull/1090 PR: https://git.openjdk.org/jfx/pull/1090 From mstrauss at openjdk.org Mon Apr 17 04:53:39 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 17 Apr 2023 04:53:39 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v2] In-Reply-To: References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> <0ZqMcHZ78UF04XZFUQ6H1yv016hFX_E9XvThZtAIwB8=.5822a500-5872-46a9-a315-8a4a509a91c7@github.com> Message-ID: On Mon, 17 Apr 2023 03:08:27 GMT, Nir Lisker wrote: >> Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: >> >> revert a change in Menu > > modules/javafx.controls/src/main/java/javafx/scene/control/TableColumnBase.java line 738: > >> 736: *

>> 737: * The {@code TableColumnBase} class allows registration of listeners which will be notified when editing occurs. >> 738: * Note that {@code TableColumnBase} is not a {@link Node}, and therefore no visual events will be fired on it. > > Isn't this true for the other classes here as well, like `Tab`? Might it be worth saying this in the other classes too then, or even on `EventTarget` itself (something like "Note that implementing classes that are not a `Node` don't receive visual events")? > I would also give an example or 2 of what "visual events" are since this term is not defined anywhere that I know of. I don't know what "visual events" are, maybe input events? Anyway, the added value of this entire javadoc seems to be rather low, I'm inclined to just remove it entirely. By the way, there's a great documentation of the JavaFX event system at https://docs.oracle.com/javase/8/javafx/events-tutorial/events.htm. It would be really helpful if we could add this to the JavaFX codebase in the future. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1090#discussion_r1168159255 From nlisker at openjdk.org Mon Apr 17 05:08:44 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Mon, 17 Apr 2023 05:08:44 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v2] In-Reply-To: References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> <0ZqMcHZ78UF04XZFUQ6H1yv016hFX_E9XvThZtAIwB8=.5822a500-5872-46a9-a315-8a4a509a91c7@github.com> Message-ID: On Mon, 17 Apr 2023 04:51:03 GMT, Michael Strau? wrote: > I don't know what "visual events" are, maybe input events? I thought something like that too, including scroll and touch events. Maybe @kevinrushforth knows. > Anyway, the added value of this entire javadoc seems to be rather low, I'm inclined to just remove it entirely. I don't think I mind removing it. My more general concern is that it's not obvious what events can be registered on different `EventTarget`s. > By the way, there's a great documentation of the JavaFX event system at https://docs.oracle.com/javase/8/javafx/events-tutorial/events.htm. It would be really helpful if we could add this to the JavaFX codebase in the future. Yes, I had an idea to link to the tutorials when working on controls documentation (https://bugs.openjdk.org/browse/JDK-8252550). The problem is that we don't have access to them and can't update them if they are out of date. Embedding them is probably too verbose. Linking looks like the better option. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1090#discussion_r1168168270 From nlisker at openjdk.org Mon Apr 17 05:44:45 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Mon, 17 Apr 2023 05:44:45 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v2] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: On Sat, 15 Apr 2023 01:36:48 GMT, John Hendrikx wrote: >> modules/javafx.graphics/src/main/java/com/sun/javafx/scene/TreeShowingExpression.java line 44: >> >>> 42: * an observable form. >>> 43: */ >>> 44: public class TreeShowingExpression extends ReadOnlyBooleanPropertyBase { >> >> Maybe you could rename the class to `TreeShowingProperty`? > > Yeah, that would definitely be better. In `Node` we have `TreeVisiblePropertyReadOnly`. Best to align it with the other properties and remove the "ReadOnly" part. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1092#discussion_r1168188290 From mstrauss at openjdk.org Mon Apr 17 06:00:21 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 17 Apr 2023 06:00:21 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v2] In-Reply-To: References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> <0ZqMcHZ78UF04XZFUQ6H1yv016hFX_E9XvThZtAIwB8=.5822a500-5872-46a9-a315-8a4a509a91c7@github.com> Message-ID: <6O3V_eAbDamDmWIuzB0I4qPjMSLVSgIx9acUsh7BV68=.65bf3e9e-010b-4b8b-9754-d30e4ecfc8f4@github.com> On Mon, 17 Apr 2023 05:05:48 GMT, Nir Lisker wrote: >> I don't know what "visual events" are, maybe input events? >> Anyway, the added value of this entire javadoc seems to be rather low, I'm inclined to just remove it entirely. >> >> By the way, there's a great documentation of the JavaFX event system at https://docs.oracle.com/javase/8/javafx/events-tutorial/events.htm. It would be really helpful if we could add this to the JavaFX codebase in the future. > >> I don't know what "visual events" are, maybe input events? > > I thought something like that too, including scroll and touch events. Maybe @kevinrushforth knows. > >> Anyway, the added value of this entire javadoc seems to be rather low, I'm inclined to just remove it entirely. > > I don't think I mind removing it. My more general concern is that it's not obvious what events can be registered on different `EventTarget`s. > >> By the way, there's a great documentation of the JavaFX event system at https://docs.oracle.com/javase/8/javafx/events-tutorial/events.htm. It would be really helpful if we could add this to the JavaFX codebase in the future. > > Yes, I had an idea to link to the tutorials when working on controls documentation (https://bugs.openjdk.org/browse/JDK-8252550). The problem is that we don't have access to them and can't update them if they are out of date. Embedding them is probably too verbose. Linking looks like the better option. I've removed the documentation from `TableColumnBase` and instead added a paragraph to the class documentation of both `TableColumn` and `TreeTableColumn`. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1090#discussion_r1168206290 From mstrauss at openjdk.org Mon Apr 17 06:00:19 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 17 Apr 2023 06:00:19 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v4] In-Reply-To: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> Message-ID: > This PR adds the following methods to the `EventTarget` interface: > 1. `addEventHandler` > 2. `removeEventHandler` > 3. `addEventFilter` > 4. `removeEventFilter` Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: doc changes ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1090/files - new: https://git.openjdk.org/jfx/pull/1090/files/cec4b90b..2557fb2f Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1090&range=03 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1090&range=02-03 Stats: 32 lines in 3 files changed: 18 ins; 12 del; 2 mod Patch: https://git.openjdk.org/jfx/pull/1090.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1090/head:pull/1090 PR: https://git.openjdk.org/jfx/pull/1090 From nlisker at openjdk.org Mon Apr 17 06:24:47 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Mon, 17 Apr 2023 06:24:47 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v4] In-Reply-To: References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> Message-ID: <2wzX0EGONTfHF84D8f2vDJICHBzlKWeuJUQOujdMs18=.c7e7c41e-f95f-402f-bcce-df0522e8c85c@github.com> On Mon, 17 Apr 2023 06:00:19 GMT, Michael Strau? wrote: >> This PR adds the following methods to the `EventTarget` interface: >> 1. `addEventHandler` >> 2. `removeEventHandler` >> 3. `addEventFilter` >> 4. `removeEventFilter` > > Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: > > doc changes Marked as reviewed by nlisker (Reviewer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1090#pullrequestreview-1387343734 From jhendrikx at openjdk.org Mon Apr 17 07:15:48 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 17 Apr 2023 07:15:48 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v3] In-Reply-To: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: <9evitqgiPi50dOK7bgQWhNwLjMWSXFygebcGXTy79js=.d0eafa1d-b777-4874-ba9f-25a05428233a@github.com> > These changes use base classes for custom properties where possible for the `ExpressionHelper` logic instead of duplicating these each time. John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Rename properties to be more consistent ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1092/files - new: https://git.openjdk.org/jfx/pull/1092/files/eda5d621..c95635be Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1092&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1092&range=01-02 Stats: 662 lines in 6 files changed: 320 ins; 320 del; 22 mod Patch: https://git.openjdk.org/jfx/pull/1092.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1092/head:pull/1092 PR: https://git.openjdk.org/jfx/pull/1092 From nlisker at openjdk.org Mon Apr 17 07:16:43 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Mon, 17 Apr 2023 07:16:43 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v2] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: On Fri, 14 Apr 2023 09:47:45 GMT, John Hendrikx wrote: >> These changes use base classes for custom properties where possible for the `ExpressionHelper` logic instead of duplicating these each time. > > John Hendrikx has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: > > Use property base classes where possible Marked as reviewed by nlisker (Reviewer). modules/javafx.graphics/src/main/java/javafx/scene/transform/Transform.java line 675: > 673: */ > 674: private static abstract class LazyBooleanProperty > 675: extends ReadOnlyBooleanPropertyBase { You can put this in the line above. ------------- PR Review: https://git.openjdk.org/jfx/pull/1092#pullrequestreview-1387291599 PR Review Comment: https://git.openjdk.org/jfx/pull/1092#discussion_r1168193384 From jhendrikx at openjdk.org Mon Apr 17 07:17:44 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 17 Apr 2023 07:17:44 GMT Subject: RFR: 8306021: Add event handler management to EventTarget [v4] In-Reply-To: References: <5BIM8D2acRWXNCALew4jS8OrndcHWMWC9-hCDCkvLwI=.f1283fbc-0421-48d1-b81d-b979437d1770@github.com> Message-ID: On Mon, 17 Apr 2023 06:00:19 GMT, Michael Strau? wrote: >> This PR adds the following methods to the `EventTarget` interface: >> 1. `addEventHandler` >> 2. `removeEventHandler` >> 3. `addEventFilter` >> 4. `removeEventFilter` > > Michael Strau? has updated the pull request incrementally with one additional commit since the last revision: > > doc changes Marked as reviewed by jhendrikx (Committer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1090#pullrequestreview-1387409041 From jhendrikx at openjdk.org Mon Apr 17 07:23:40 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 17 Apr 2023 07:23:40 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v4] In-Reply-To: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: > These changes use base classes for custom properties where possible for the `ExpressionHelper` logic instead of duplicating these each time. John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Fix review comment ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1092/files - new: https://git.openjdk.org/jfx/pull/1092/files/c95635be..b2d1434a Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1092&range=03 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1092&range=02-03 Stats: 2 lines in 1 file changed: 0 ins; 1 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1092.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1092/head:pull/1092 PR: https://git.openjdk.org/jfx/pull/1092 From mstrauss at openjdk.org Mon Apr 17 07:35:48 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 17 Apr 2023 07:35:48 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v4] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: On Mon, 17 Apr 2023 07:23:40 GMT, John Hendrikx wrote: >> These changes use base classes for custom properties where possible for the `ExpressionHelper` logic instead of duplicating these each time. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Fix review comment Marked as reviewed by mstrauss (Committer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1092#pullrequestreview-1387444153 From nlisker at openjdk.org Mon Apr 17 07:35:50 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Mon, 17 Apr 2023 07:35:50 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v4] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: On Mon, 17 Apr 2023 07:23:40 GMT, John Hendrikx wrote: >> These changes use base classes for custom properties where possible for the `ExpressionHelper` logic instead of duplicating these each time. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Fix review comment modules/javafx.graphics/src/main/java/javafx/scene/Node.java line 8566: > 8564: addToSceneDirtyList(); > 8565: } > 8566: if (treeVisibleProperty != null) { This change causes the property to not be initialized when this method is called. I think that this is fine as I don't see any reliance on the previous behavior, but it might be worth to take another look at that. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1092#discussion_r1168295382 From nlisker at openjdk.org Mon Apr 17 07:40:48 2023 From: nlisker at openjdk.org (Nir Lisker) Date: Mon, 17 Apr 2023 07:40:48 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v4] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: On Mon, 17 Apr 2023 07:23:40 GMT, John Hendrikx wrote: >> These changes use base classes for custom properties where possible for the `ExpressionHelper` logic instead of duplicating these each time. > > John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: > > Fix review comment Marked as reviewed by nlisker (Reviewer). ------------- PR Review: https://git.openjdk.org/jfx/pull/1092#pullrequestreview-1387450571 From jhendrikx at openjdk.org Mon Apr 17 08:40:46 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 17 Apr 2023 08:40:46 GMT Subject: RFR: JDK-8305885: Use ReadOnly*PropertyBase class where possible [v4] In-Reply-To: References: <-_tKzXh3AlOeW49h_qHCVzEWB8ZXIBMfQ3k-AQk7Bhc=.2d67445f-8141-4c32-87e2-a6e6d10616b9@github.com> Message-ID: On Mon, 17 Apr 2023 07:33:07 GMT, Nir Lisker wrote: >> John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix review comment > > modules/javafx.graphics/src/main/java/javafx/scene/Node.java line 8566: > >> 8564: addToSceneDirtyList(); >> 8565: } >> 8566: if (treeVisibleProperty != null) { > > This change causes the property to not be initialized when this method is called. I think that this is fine as I don't see any reliance on the previous behavior, but it might be worth to take another look at that. Yeah, I think this is what was originally intended here; it's pointless to "create" the property just to invalidate it, as there is no one listening, because if there was someone listening, the property would have to have been created already. So this is causing the property to be created by default for all nodes without a good reason. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1092#discussion_r1168363846 From r.lichtenberger at gmail.com Mon Apr 17 08:46:30 2023 From: r.lichtenberger at gmail.com (Robert Lichtenberger) Date: Mon, 17 Apr 2023 10:46:30 +0200 Subject: Content Graph In-Reply-To: References: Message-ID: <5b29f54f-0b5e-8c60-1fe5-8bcc3f34da08@gmail.com> From a testing perspective it seems a good idea to have a more abstract "document graph" to find certain elements in the UI (to check their state is correct). However I see two problems, shown as inline comments below... Am 13.04.23 um 20:55 schrieb Michael Strau?: > Now also suppose a method `printContentGraph(ContentNode root)`, which > does the same as before, but works on the content graph. > This is the output of that method: > > javafx.scene.layout.VBox > ....javafx.scene.control.MenuButton > ........javafx.content.Text This requires that a MenuButton always has a text, however a Skin could exist that does not contain any text node (but only a bitmap, a simple shape, etc.). AFAIK Skins separate controls from their concrete representation. > 2) Defining the Content Model > > The content graph consists of the content model of all participating > controls. Implementors are responsible for defining the content model > of a control by overriding the protected `buildContentModel` method, > and adding the content that is significant for the control: Which means that the abovementioned use case as a tool for UI testing cannot be executed if any of the UI libraries (ControlsFX comes to mind) I use does not support this new model. Best regards, Robert From jhendrikx at openjdk.org Mon Apr 17 11:16:36 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 17 Apr 2023 11:16:36 GMT Subject: RFR: JDK-8245919: Region#padding property rendering error [v2] In-Reply-To: References: Message-ID: > Fix bug in CSS caching code that could reset values on unrelated nodes. > > The bug occurs due to a cache entry being constructed incorrectly when the initial node that triggered the cache entry creation has user set values. The calculated values for properties with a user set value were omitted in the cache entry, and other nodes that later share the same entry would incorrectly assume the omitted property was unstyled and were therefore reset to their default values. John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Fix typo ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1072/files - new: https://git.openjdk.org/jfx/pull/1072/files/e0bb42d9..5c6e5c1f Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1072&range=01 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1072&range=00-01 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.org/jfx/pull/1072.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1072/head:pull/1072 PR: https://git.openjdk.org/jfx/pull/1072 From jhendrikx at openjdk.org Mon Apr 17 11:25:53 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 17 Apr 2023 11:25:53 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v4] In-Reply-To: References: Message-ID: <57gXK6zVBHVUnd9iFuuZalFA0ghS2M0yMZJ5GFyGfbQ=.f411006e-30f0-4c9c-8cb4-c3a657be4829@github.com> > Description copied from issue: > > There are up to two additional invalidations performed that really should be avoided, causing downstream fluent bindings to be recomputed with the same values. This is very confusing as these should only be called when there is an actual change, and not called for the same value multiple times in a row. > > These two extra invalidations have two different causes, each causing an additional invalidation to be triggered: > > 1) ObjectBinding's `isObserved` is delayed slightly. When you add a listener, the listener is added internally and the binding is made valid; this triggers some downstream activity which checks the `isObserved` status to decide whether to start observation of properties -- unfortunately this still returns `false` at that time. A work-around for this existed by calling `getValue` again in `LazyObjectBinding` with a huge comment explaining why this is needed. Although this works, it still means that a downstream function like `map` is called an additional time while it should really only be called once. > > The solution is to ensure `isObserved` returns `true` before the `ExpressionHelper` is called. Already verified this solves the problem. This also means the work-around in `LazyObjectBinding` is no longer needed, which seems like a big win. > > 2) The second additional call originates from a different issue. When `ConditionalBinding` (which implements the `when` construct) sees its condition property changing, it always invalidates itself. This is however only necessary if the current cached value (if it was valid) differs from the current source value. To prevent an unnecessary invalidation, and the resulting revalidation calls that this will trigger, a simple check to see if the value actually changed before invalidating solves this problem. John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Fix review comments ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1056/files - new: https://git.openjdk.org/jfx/pull/1056/files/472cefb2..c17bc639 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1056&range=03 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1056&range=02-03 Stats: 25 lines in 1 file changed: 12 ins; 0 del; 13 mod Patch: https://git.openjdk.org/jfx/pull/1056.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1056/head:pull/1056 PR: https://git.openjdk.org/jfx/pull/1056 From jhendrikx at openjdk.org Mon Apr 17 11:25:55 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 17 Apr 2023 11:25:55 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v3] In-Reply-To: References: <-LO-7b7wb0L55OTfiObMEeAAXn3PjPSe5v7bVq2EMsc=.48b6595b-543d-4630-aec6-f6c11b597851@github.com> Message-ID: On Sun, 9 Apr 2023 22:48:22 GMT, Nir Lisker wrote: >> John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: >> >> Address review comments >> >> - Added extra tests cases that count invalidations >> - Added explanatory comment > > modules/javafx.base/src/test/java/test/javafx/beans/value/ObservableValueWhenTest.java line 260: > >> 258: assertEquals(0, observedInvalidations.get()); >> 259: >> 260: when.getValue(); // would make no difference, inactive when bindings are always valid > > Did you mean "always valid when bindings are inactive"? Or maybe that when the binding is valid the listener is inactive? This sentence is confusing to me. :-) The confusing part is because I referred to the `when` construct here. I've changed it to: // would make no difference, inactive "when" bindings are always valid I also put quotes around the other uses where necessary. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1056#discussion_r1168536579 From jhendrikx at openjdk.org Mon Apr 17 11:32:44 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 17 Apr 2023 11:32:44 GMT Subject: RFR: JDK-8304323 Provide infrastructure to make it possible for properties to delay listener registration [v2] In-Reply-To: References: Message-ID: > This PR contains changes to make it easier to implement properties which want to conserve resources until they're observed themselves. > > `isObserved` is promoted from `ObjectBinding` to the `ObservableValue` interface, allowing you to ask any `ObservableValue` if it is currently observed (ie. if it has any listeners registered on it). All JavaFX `ObservableValue`s implementations are modified to implement this method. > > The protected methods `observed` and `unobserved` are added to all extendable (non final) `ObservableValue`s provided by JavaFX. The `observed` call back is only called when the observable currently has 0 listeners and will soon have 1 listener. During the call back, `isObserved` still returns `false` (see below for why this was chosen). The `unobserved` call back is only called when the last listener was removed and the observable has 0 listeners. During the call back, `isObserved` will already return `false`. > > The reason why `observed` is called before `isObserved` starts returning `true` (and also why `unobserved` works the opposite) is to make it easy to implement a parent-child relationship where a nested property becoming observed may need to trigger behavior in its parent. Given a parent class and two nested properties `foo` and `bar`: > > class FooProperty extends ObjectPropertyBase { > void observed() { > nestedPropertyObserved(); // call to parent > } > > void unobserved() { > nestedPropertyUnobserved(); // call to parent > } > } > > The parent may determine whether any of the properties is observed with a helper: > > private boolean isANestedPropertyObserved() { > return foo.isObserved() || bar.isObserved(); > } > > The `nestedPropertyObserved` and `nestedPropertyUnobserved` methods can now be implemented simply as: > > private void nestedPropertyObserved() { > if (!isANestedPropertyObserved()) { > // take action as no properties were observed before, but now one will become observed > } > } > > private void nestedPropertyUnobserved() { > if (!isANestedPropertyObserved()) { > // take action as a property was observed before, but the last listener is about to be removed > } > } > > If `isObserved` would change immediately, this becomes more difficult as the observed status of the property that has just become observed would need to be excluded to determine if this is the first observation of a nested property or a later one. > > - Add `isObserved` to `ObservableValue` to check if it is observed and implement it in all overriding classes > - Add `observed`/`unobserved` protected methods to all extendable observables > - Use *Base classes in a few places (avoids duplication code) > - Simplify `LazyObjectBinding` > - In `ObjectBinding`, `isObserved` has become public as it is specified by the `ObservableValue` interface now John Hendrikx has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains two commits: - Merge branch 'master' into feature/delayed-infra - Add delayed listener registration support - Add isObserved to ObservableValue to check if it is observed - Add observed/unobserved protected methods to all subclassable observables - Use *Base classes in a few places (avoids duplication code) - Simplify LazyObjectBinding - In ObjectBinding, isObserved has become public as it is specified by the ObservableValue interface now ------------- Changes: https://git.openjdk.org/jfx/pull/1023/files Webrev: https://webrevs.openjdk.org/?repo=jfx&pr=1023&range=01 Stats: 1225 lines in 43 files changed: 802 ins; 211 del; 212 mod Patch: https://git.openjdk.org/jfx/pull/1023.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1023/head:pull/1023 PR: https://git.openjdk.org/jfx/pull/1023 From jhendrikx at openjdk.org Mon Apr 17 12:49:00 2023 From: jhendrikx at openjdk.org (John Hendrikx) Date: Mon, 17 Apr 2023 12:49:00 GMT Subject: RFR: JDK-8290310: ChangeListener events are incorrect or misleading when a nested change occurs [v7] In-Reply-To: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> References: <-c9W_6MJ7b6-UeF6rp2AOjAGFYZGyd3poJo-LjXqj8s=.7107724a-fb24-4f68-90fe-042e69e320b5@github.com> Message-ID: > This provides and uses a new implementation of `ExpressionHelper`, called `ListenerManager` with improved semantics. > > # Behavior > > |Listener...|ExpressionHelper|ListenerManager| > |---|---|---| > |Invocation Order|In order they were registered, invalidation listeners always before change listeners|(unchanged)| > |Removal during Notification|All listeners present when notification started are notified, but excluded for any nested changes|Listeners are removed immediately regardless of nesting| > |Addition during Notification|Only listeners present when notification started are notified, but included for any nested changes|New listeners are never called during the current notification regardless of nesting| > > ## Nested notifications: > > | |ExpressionHelper|ListenerManager| > |---|---|---| > |Type|Depth first (call stack increases for each nested level)|(same)| > |# of Calls|Listeners * Depth (using incorrect old values)|Collapses nested changes, skipping non-changes| > |Vetoing Possible?|No|Yes| > |Old Value correctness|Only for listeners called before listeners making nested changes|Always| > > # Performance > > |Listener|ExpressionHelper|ListenerManager| > |---|---|---| > |Addition|Array based, append in empty slot, resize as needed|(same)| > |Removal|Array based, shift array, resize as needed|(same)| > |Addition during notification|Array is copied, removing collected WeakListeneres in the process|Tracked (append at end)| > |Removal during notification|As above|Entry is `null`ed| > |Notification completion with changes|-|Null entries (and collected WeakListeners) are removed| > |Notifying Invalidation Listeners|1 ns each|(same)| > |Notifying Change Listeners|1 ns each (*)|2-3 ns each| > > (*) a simple for loop is close to optimal, but unfortunately does not provide correct old values > > # Memory Use > > Does not include alignment, and assumes a 32-bit VM or one that is using compressed oops. > > |Listener|ExpressionHelper|ListenerManager|OldValueCaching ListenerManager| > |---|---|---|---| > |No Listeners|none|none|none| > |Single InvalidationListener|16 bytes overhead|none|none| > |Single ChangeListener|20 bytes overhead|none|16 bytes overhead| > |Multiple listeners|57 + 4 per listener (excluding unused slots)|57 + 4 per listener (excluding unused slots)|61 + 4 per listener (excluding unused slots)| > > # About nested changes > > Nested changes are simply changes that are made to a property that is currently in the process of notifying its listeners. This all occurs on the same thread, and a nested change is nothing more than the same property being modified, triggering its listeners again deeper in the call stack with another notification, while higher up the call stack a notification is still being handled: > > (top of stack) > fireValueChangedEvent (property A) <-- nested notification > setValue (property A) <-- listener modifies property A > changed (Listener 1) <-- a listener called by original notification > fireValueChangedEvent (property A) <-- original notification > > ## How do nested changes look? > > Let's say we have three listeners, where the middle listener changes values to uppercase. When changing a property with the initial value "A" to a lowercase "b" the listeners would see the following events: > > ### ExpressionHelper > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | | > | 1 |T5 | | |b -> B| | > | 0 |T6 | | |A -> B|Top level loop is resumed| > > Note how the values received by the 3rd listener are non-sensical. It receives two changes both of which changes to B from old values that are out of order. > > ### ListenerManager (new) > This how ListenerManager sends out these events: > |Nesting Level|Time|Listener 1|Listener 2|Listener 3|Comment| > |---|---|---|---|---|---| > | 0 |T1 |A -> b| | | | > | 0 |T2 | |A -> b| |Value is changed to B| > | 1 |T3 |b -> B| | | A nested loop started deeper on the call stack | > | 1 |T4 | |b -> B| | The nested loop is terminated early at this point | > | 0 |T5 | | |A -> B|Top level loop is resumed| > > Note how the 3rd listener now receives an event that reflects what actually happened from its perspective. Also note that less events overall needed to be send out. > > # About Invocation Order > > A lot of code depends on the fact that an earlier registered listener of the same type is called **before** a later registered later of the same type. For listeners of different types it is a bit less clear. What is clear however is that invalidation and change listeners are defined by separate interfaces. Mixing their invocations (to conserve registration order) would not make sense. Historically, invalidation listeners are called before change listeners. No doubt, code will be (unknowingly) relying on this in today's JavaFX applications so changing this is not recommended. Perhaps there is reason to say that invalidation listeners should be called first as they're defined by the super interface of `ObservableValue` which introduces change listeners. > > # About Listener Add/Remove performance > > Many discussions have happened in the past to improve the performance of removing listeners, ranging from using maps to ordered data structures with better remove performance. Often these solutions would subtly change the notification order, or increase the overhead per listener significantly. > > But these discussions never really looked at the other consequences of having tens of thousands of listeners. Even if listeners could be removed in something approaching O(1) time (additions are already O(1) and so are not the issue), what about the performance of notifying that many listeners? That will still be O(n), and so even if JavaFX could handle addition and removal of that many listeners comfortably, actually using a property with that many listeners is still impossible as it would block the FX thread for far too long when sending out that many notifications. > > Therefore, I'm of the opinion that "fixing" this "problem" is pointless. Instead, having that many listeners should be considered a design flaw in the application. A solution that registers only a single listener that updates a shared model may be much more appropriate. > > # About Old Value Correctness > ...and why it is important. > > A change listener provides a callback that gives the old and the new value. One may reasonably expect that these values are never the same, and one may reasonably expect that the given old value is the same as the previous invocation's new value (if there was a previous invocation). > > In JavaFX, many change listeners are used for important tasks, ranging from reverting changes in order to veto something, to registering and unregistering listeners on properties. Many of those change listeners do not care about the old value, but there are a significant number that use it and rely on it being correct. A common example is the registering of a listener on the "new" value, and removing the same listener from the "old" value in order to maintain a link to some other property that changes location: > > (obs, old, current) -> { > if (old != null) { > old.removeListener(x); > } > if (current != null) { > current.addListener(x); > } > } > > The above code looks bug free, and it would be if the provided old values are always correct. Unfortunately, this does not have to be the case. When a nested change is made (which can be made by a user registered listener on the same property), `ExpressionHelper` makes no effort to ensure that for all registered listener the received old and new values make sense. This leads to listeners being notified twice with the same "new" value for example, but with a different old value. Imagine the above listener receives the following change events: > > scene1 becomes scene3 > scene2 becomes scene3 > > The above code would remove its listeners from `scene1` and `scene2`, and register two listeners on `scene3`. This leads to the listener being called twice when something changes. When later the scene changes to `scene4`, it receives: > > scene3 becomes scene4 > > Because it registered its listener twice on `scene3`, and only removes one of them, it now has listeners on both `scene3` and `scene4`. > > Clearly it is incredibly important that changes make sense, or even simple code that looks innocuous becomes problematic. > > # The PR > > The `ListenerManager` differs from `ExpressionHelper` in the following ways: > - Provides correct old/new values to `ChangeListener`s under all circumstances > - Unnecessary change events are never sent > - Single invalidation or change listeners are inlined directly into the observable class (in other words, properties with only a single listener don't take up any extra space at all) > - Performance is slightly worse when calling **change** listeners (but remember that `ExpressionHelper` is not following the contract). > - Removed listeners are never called after being removed (even if they were part of the initial list when the notification triggered) > - Added listeners are only called when a new non-nested (top level) notification starts > - Locking and maintaining the listener list works a bit differently -- the main takeaway is that the list indices remain the same when modified during nested modifications, which allows using the same list no matter how deep the nesting > - No reference is stored to the ObservableValue and no copy is kept of the current value > - Memory use when there is more than 1 listener should be similar, and better when not > - Although complicated, the code is I think much better separated, and more focused on accomplishing a single task: > - `ListenerManager` manages the listener storage in property classes, and the transformation between the listener variants (it either uses listeners directly, or uses a `ListenerList` when there are multiple listeners). > - `ListenerListBase` handles the locking and compacting of its listener lists. > - `ListenerList` which extends `ListenerListBase` is only concerned with the recursion algorithm for notification. > - `ArrayManager` handles resizing and reallocating of arrays. > - There are variants of `ListenerList` and `ListenerManager` which can cache their old values when its not possible to supply these (this has a cost, and is what `ExpressionHelper` does by default). > > The notification mechanism deals with nested notifications by tracking how many listeners were notified already before the nested notification occurs. For example, if 5 listeners were notified, and then listener 5 makes a nested change, then in that nested change only the first 5 listeners are notified again (if they still exist). The nested loop is then terminated early, at which point the top level loop resumes: it continues where it left of and notifies listener 6 and so on. This ensures that all notifications are always correct, and that listeners that "veto" changes can effectively block later listeners from seeing those at all. > > For example, if the first listener always uppercases any received values, then any succeeding listeners will always see only uppercase values. The first listener receives two notifications (`X -> a` and `a -> A`), and the second receives only `X -> A`. Contrast this with the old `ExpressionHelper`, which sends odd notifications to the second listener (`a -> A` and `X -> A`, in that order). > > Unfortunately, due to a somewhat weird design choice in the PropertyBase classes, the strategy of not having to cache the "current value" (or old value) can't be used (it can only be used for Bindings for now). So there is another variant of this helper, called `OldValueCachingListenerHelper`, with some slight differences: > > - Has an extra field for storing the old value when there are any `ChangeListener`s active > - Can't store a `ChangeListener` inline; a minimal wrapper is needed to track the old value (ExpressionHelper does the same) John Hendrikx has updated the pull request incrementally with one additional commit since the last revision: Use an overridable method to store latest value ------------- Changes: - all: https://git.openjdk.org/jfx/pull/1081/files - new: https://git.openjdk.org/jfx/pull/1081/files/c86cab5d..b97c574a Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=06 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=1081&range=05-06 Stats: 41 lines in 6 files changed: 18 ins; 9 del; 14 mod Patch: https://git.openjdk.org/jfx/pull/1081.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/1081/head:pull/1081 PR: https://git.openjdk.org/jfx/pull/1081 From duke at openjdk.org Mon Apr 17 18:13:38 2023 From: duke at openjdk.org (Martin Fox) Date: Mon, 17 Apr 2023 18:13:38 GMT Subject: RFR: 8278924: [Linux] Robot key test can fail if multiple keyboard layouts are installed [v3] In-Reply-To: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> References: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> Message-ID: > The Robot implementation on Linux did not consult the current layout when mapping from a KeyCode to a hardware code. Internally it retrieved results for all the layouts but just picked the first one it saw leading to random effects. Though not part of the original bug report, the code also ignored the shift level when choosing which result to pick. On a French layout the dollar sign is on two keys (AltGr 4 is the second one) and the code could choose either one. Same is true for pound. > > This PR consults the current layout and only on shift level 0 which is the same level used in get_glass_key to figure out which KeyCode to assign when generating a KeyEvent. Martin Fox has updated the pull request incrementally with one additional commit since the last revision: The Robot code now correctly targets numlock keypad keys and keys that always appear on group 0. ------------- Changes: - all: https://git.openjdk.org/jfx/pull/718/files - new: https://git.openjdk.org/jfx/pull/718/files/51fcd047..ca9f5bf7 Webrevs: - full: https://webrevs.openjdk.org/?repo=jfx&pr=718&range=02 - incr: https://webrevs.openjdk.org/?repo=jfx&pr=718&range=01-02 Stats: 77 lines in 2 files changed: 48 ins; 2 del; 27 mod Patch: https://git.openjdk.org/jfx/pull/718.diff Fetch: git fetch https://git.openjdk.org/jfx.git pull/718/head:pull/718 PR: https://git.openjdk.org/jfx/pull/718 From duke at openjdk.org Mon Apr 17 18:43:45 2023 From: duke at openjdk.org (Martin Fox) Date: Mon, 17 Apr 2023 18:43:45 GMT Subject: RFR: 8278924: [Linux] Robot key test can fail if multiple keyboard layouts are installed [v3] In-Reply-To: References: <5SPjvG13-ikrrvdyb0M7KJNSmvRIM-bWEXTxLNka8Jg=.49267d9e-a893-4251-88ce-667da5567405@github.com> Message-ID: <2QVDYZAcsQpXi4ZsBrutRaRc7dUkT8JMLp55als-1Eg=.d429e647-f1fc-41de-aa0e-6148d59bcba6@github.com> On Mon, 17 Apr 2023 18:13:38 GMT, Martin Fox wrote: >> The Robot implementation on Linux did not consult the current layout when mapping from a KeyCode to a hardware code. Internally it retrieved results for all the layouts but just picked the first one it saw leading to random effects. Though not part of the original bug report, the code also ignored the shift level when choosing which result to pick. On a French layout the dollar sign is on two keys (AltGr 4 is the second one) and the code could choose either one. Same is true for pound. >> >> This PR consults the current layout and only on shift level 0 which is the same level used in get_glass_key to figure out which KeyCode to assign when generating a KeyEvent. > > Martin Fox has updated the pull request incrementally with one additional commit since the last revision: > > The Robot code now correctly targets numlock keypad keys and keys that always appear on group 0. The results returned from `gdk_keymap_get_entries_for_keyval` match the way the keys events are delivered from the OS. The numlock state can affect the `level` and some keys (like ones on the numeric keypad) always appear on `group` 0 even if that's not the current group. When searching through the results we have to use `translate_keyboard_state` to find the correct group and level to match against. Code has been updated along with a few minor fixes. ------------- PR Comment: https://git.openjdk.org/jfx/pull/718#issuecomment-1511890495 From mstrauss at openjdk.org Mon Apr 17 18:57:35 2023 From: mstrauss at openjdk.org (Michael =?UTF-8?B?U3RyYXXDnw==?=) Date: Mon, 17 Apr 2023 18:57:35 GMT Subject: RFR: JDK-8303897 ObservableValue's when binding should only invalidate when strictly needed [v4] In-Reply-To: <57gXK6zVBHVUnd9iFuuZalFA0ghS2M0yMZJ5GFyGfbQ=.f411006e-30f0-4c9c-8cb4-c3a657be4829@github.com> References: <57gXK6zVBHVUn