Compare commits

..

89 Commits

Author SHA1 Message Date
Alexey Ushakov
1f0f43b4da JBR-1430 Problem with JNA when username contains unicode symbol
Added unicode conversion
2021-04-07 19:27:46 +03:00
Artem Semenov
04f1cf9b47 JBR-3241: MAke a11y element for combobox 2021-04-07 17:23:49 +03:00
Jim Laskey
80c6e03ec4 JBR-2607 backport the fix for crash in [libjimage] ImageStrings::find from OpenJDK
backported from OpenJDK - 8166727: javac crashed: [jimage.dll+0x1942] ImageStrings::find+0x28

Reviewed-by: iklam, alanb
2021-04-07 14:33:38 +07:00
Artem Semenov
9001a78701 JBR-3274: macOS: SIGILL at [libsystem_kernel] __kill -[PlatformAxNavigableText accessibilitySelectedTextAttribute] 2021-04-05 14:47:34 +03:00
Artem Semenov
703cab8d0d JBR-3240: MAke a11y element for TabGroup 2021-04-02 15:51:57 +03:00
Nikita Gubarkov
3c9cdc9251 JBR-3269 Disabled subpixel antialiasing for MacOS Big Sur and newer 2021-04-02 01:24:57 +03:00
Denis Konoplev
032805520d JBR-3214: CR: remove double negation 2021-04-01 16:54:47 +03:00
Dmitry Batrak
b37f7cfdb1 JBR-3255 Applying 'incline' transform might change character's advance 2021-03-30 18:37:21 +03:00
Denis Konoplev
3668d631ca JBR-3214: Reuse openjdk logic and add unicode keycodes 2021-03-30 16:12:29 +03:00
Denis Konoplev
7fa3ea24ac JBR-2509: Fix Escape emulation after Cmd . 2021-03-30 16:05:16 +03:00
Artem Semenov
8a521cbf64 JR-CR-776: JBR-3239: MAke a11y component for ScrollView 2021-03-30 13:43:22 +03:00
Denis Konoplev
fe9601aa6d JBR-3214: Initialize stack variables to fix dead key prefix and enable support on aarch64 2021-03-29 20:06:22 +03:00
Artem Semenov
65e8162d67 JR-CR-775: JBR-3188: NSAccessibilityNavigableStaticText 2021-03-26 14:35:34 +03:00
Artem Semenov
b99be427ce JR-CR-774: JBR-3218: IDEA crash with opening drop down menu and click whatever next. 2021-03-24 18:38:32 +03:00
Denis Konoplev
6b3b011d0b Revert "JBR-2509: Fix Escape emulation after Cmd ."
This reverts commit f096bd2b
2021-03-24 14:01:10 +03:00
Denis Konoplev
b53ef867e4 Revert "JBR-2509: Remove Fokin code."
This reverts commit 99a8e455
2021-03-24 14:01:10 +03:00
Denis Konoplev
215fd32738 Revert "JBR-2509: Turn on option on M1"
This reverts commit 542ee611
2021-03-24 14:01:10 +03:00
Artem Semenov
921603e356 JBR-3028: macOS: SIGILL at [libsystem_kernel] __kill -[PlatformAxList accessibilityParent]
JR-CR-773: JBR-3028: macOS: SIGILL at [libsystem_kernel] __kill -[PlatformAxList accessibilityParent]
2021-03-23 21:04:25 +03:00
Denis Konoplev
542ee611fc JBR-2509: Turn on option on M1 2021-03-23 19:38:58 +03:00
Denis Konoplev
99a8e45598 JBR-2509: Remove Fokin code.
Reuse openjdk logic and add unicode keycodes
2021-03-23 16:45:33 +03:00
Denis Konoplev
f096bd2b0d JBR-2509: Fix Escape emulation after Cmd . 2021-03-23 16:45:33 +03:00
Ivan Migalev
26dd87ab7c JBR-3227 Reload type of required native file dialogs each time a file dialog is requested 2021-03-23 16:00:08 +03:00
Alexey Ushakov
a6ea081ba2 JBR-3023 Gray idea frame after project open with ide.mac.transparentTitleBarAppearance.
Initiate move/resize event on first appearance of window having FULL_WINDOW_CONTENT property set
2021-03-23 00:44:30 +03:00
Artem Semenov
2e87610593 JR-CR-771: JBR-3187: NSAccessibilityStaticText 2021-03-22 20:26:07 +03:00
Artem Semenov
1c336fc03a JR-CR-768: Test for JBR-3187 and JBR-3188
Test for JBR-3187 and JBR-3188
2021-03-22 20:26:07 +03:00
Dmitry Batrak
8eafcaab24 JBR-3215 'deriveFont(float)' can return a different font (not just change the size) 2021-03-22 15:56:46 +03:00
Vitaly Provodin
c096f12994 updated JTreg exclude list 2021-03-22 06:40:23 +07:00
Alexey Ushakov
5cfc8b3629 JBR-3217 [bkp to JBR11] JDK-8262446 DragAndDrop hangs on Windows
backported JDK-8262446 without any conflicts
2021-03-20 00:26:45 +03:00
Denis Konoplev
65b3d32eca JBR-1718: Fix regression java/awt/MenuBar/DefaultMenuBarDispose.java 2021-03-19 21:30:41 +03:00
Alexey Ushakov
61de3c3065 JBR-3208 bkp from JDK17: 8255790: GTKL&F: Java 16 crashes on initialising GTKL&F on Manjaro Linux
Review: disable coretext for now, cleanup
2021-03-18 13:33:55 +03:00
Nikita Gubarkov
3b101f673b JBR-2910 Fixed font size computation (extended glyph cache for MacOS) 2021-03-18 03:59:42 +03:00
Phil Race
bd79159249 8249142: java/awt/FontClass/CreateFont/DeleteFont.sh is unstable
Reviewed-by: serb
2021-03-18 05:47:50 +07:00
Alexey Ushakov
ca4425cb21 JBR-3208 bkp from JDK17: 8255790: GTKL&F: Java 16 crashes on initialising GTKL&F on Manjaro Linux
Backported fix with some minor corrections
2021-03-17 20:50:22 +03:00
Alexey Ushakov
b386e44bf5 Revert "JBR-3066 jbr 11_10 (1145-88) crashes on IDEA startup, jbr 11_09 (1145-77) works fine"
This reverts commit e03c9829, 97c0e96a, 746affd7, e766df4b, 847705dc, f10e7aca, 9ee15508, 553e5ca6
2021-03-17 16:31:05 +03:00
Nikita Gubarkov
03995a0327 JBR-2910 Implemented extended glyph cache for MacOS 2021-03-17 01:25:08 +03:00
Vitaly Provodin
bd6a088aaf remove links to bintray - download zulu as BOOT JDK 2021-03-17 04:46:44 +07:00
Denis Konoplev
c2582f8e03 JBR-1718: Add backward compatibility 2021-03-15 16:00:58 +03:00
Denis Konoplev
c122e27068 JBR-1718: Fix MacOs handlers 2021-03-15 16:00:58 +03:00
Dmitry Batrak
52a2428c28 use GPL copyright header 2021-03-15 14:53:42 +03:00
Konstantin Bulenkov
87b60afdf7 Remove links to bintray 2021-03-14 13:03:11 +01:00
Vitaly Provodin
10069846d5 Follow-up to 8221852: reporting actual error when unprivileged symlink creation fails
fix the misprint
2021-03-12 15:47:01 +07:00
Roman Shevchenko
f06f9fe734 Follow-up to 8221852: reporting actual error when unprivileged symlink creation fails
... for a reason other that ERROR_INVALID_PARAMETER.
2021-03-11 12:16:11 +03:00
Vitaly Provodin
348e538d10 updated JTreg exclude list
JBR-3167 excluding java2d tests causing Xwayland crash
2021-03-09 06:37:34 +07:00
Dmitry Batrak
5b9ff9a29e JBR-2766 java/awt/Window/MinimumSizeDPIVariation/MinimumSizeDPIVariation.java: Wrong size 2021-03-02 19:42:44 +03:00
Dmitry Batrak
62b04983f2 JBR-3157 Maximized window with custom decorations isn't focused on showing 2021-03-02 19:00:15 +03:00
Vitaly Provodin
c40b9c8b9e JBR-1505 add jdk.jcmd module into JBR 2021-03-02 05:43:59 +07:00
Artem Semenov
46dfaeecc9 JR-CR-760:
JBR-3144 Extend test for list with list nested in Heavy Weight Window popup
2021-02-24 14:25:30 +03:00
Alexey Ushakov
e03c9829e3 JBR-3066 jbr 11_10 (1145-88) crashes on IDEA startup, jbr 11_09 (1145-77) works fine
Optimised failure handling
2021-02-20 06:57:05 -08:00
Alexey Ushakov
97c0e96a5a JBR-3066 jbr 11_10 (1145-88) crashes on IDEA startup, jbr 11_09 (1145-77) works fine
Optimised failure handling
2021-02-20 02:57:25 -08:00
Vitaly Provodin
2b559a30df JBR-3138 fix the issues with signing JNF (follow up) 2021-02-20 16:39:00 +07:00
Sean Coffey
73b4a7e79e JBR-3139 backport the fix for 8253368: TLS connection always receives close_notify exception
Reviewed-by: xuelei
(cherry picked from commit 780ac896b1)
2021-02-20 16:38:20 +07:00
Anton Tarasov
7d8aeaf7de revert: JBR-1434 "New file dialog" popup remains above all windows on switching application
java.awt.peer.WindowPeer.isLightweightDialog() method does not exist.
2021-02-20 11:23:59 +03:00
Vitaly Provodin
94390c3f1e JBR-3138 fix the issues with signing JNF 2021-02-20 14:23:45 +07:00
Artem Bochkarev
78d509ac0f JBR-3131: support custom view for system menu items 2021-02-19 19:46:11 +03:00
Nikita Gubarkov
0b6238990b JBR-2910 Implemented extended glyph cache for Linux 2021-02-17 15:13:06 +03:00
Nikita Gubarkov
c0e4afcddd JBR-2910 Implemented extended glyph cache for Windows 2021-02-17 15:12:40 +03:00
Artem Bochkarev
be6a2c4f0c JBR-3127: add possibility to load NSJavaVirtualMachine
JavaVM framework is deprecated but this class is still checked by AppKit, see https://youtrack.jetbrains.com/issue/JBR-3127#focus=Comments-27-4684465.0-0
2021-02-17 15:00:21 +03:00
Artem Bochkarev
0b8ff1a7e6 JBR-3127: set NSWindowAllowsImplicitFullScreen=NO
fixed JBR-3127 Modal dialogs invoked from modal or floating dialogs are opened in full screen
2021-02-17 15:00:20 +03:00
Dmitry Batrak
63134e091b JBR-3119 Application's panel in KDE taskbar blinks when popup window is shown
this re-fixes JBR-2934 in a different way
2021-02-17 10:43:46 +03:00
Dmitry Batrak
50ab4690de JBR-1752 Floating windows overlap modal dialogs
fix for file dialog case
2021-02-11 12:52:14 +03:00
Ivan Migalev
c790bf3ebc JBR-3068: pass default button localization if not overridden 2021-02-11 11:16:56 +03:00
Alexey Ushakov
746affd753 JBR-3066 jbr 11_10 (1145-88) crashes on IDEA startup, jbr 11_09 (1145-77) works fine
Corrected symbol name
2021-02-10 08:44:59 -08:00
Alexey Ushakov
e766df4bcc JBR-3066 jbr 11_10 (1145-88) crashes on IDEA startup, jbr 11_09 (1145-77) works fine
Added missing initializations
2021-02-10 06:17:56 -08:00
Alexey Ushakov
847705dc96 JBR-3066 jbr 11_10 (1145-88) crashes on IDEA startup, jbr 11_09 (1145-77) works fine
One more fix of compilation (on windows)
2021-02-10 09:53:00 +03:00
Alexey Ushakov
f10e7aca70 JBR-3066 jbr 11_10 (1145-88) crashes on IDEA startup, jbr 11_09 (1145-77) works fine
Fixed compile problem
2021-02-09 23:18:52 +03:00
Alexey Ushakov
9ee1550815 JBR-3066 jbr 11_10 (1145-88) crashes on IDEA startup, jbr 11_09 (1145-77) works fine
Added manual loading of harfbuzz library. Use pointers to functions to access it's API.
2021-02-09 22:31:18 +03:00
Konstantin Bulenkov
1de6eed0e1 compilation fix 2021-02-09 12:02:41 +01:00
Konstantin Bulenkov
78510922c5 Update JetBrains Mono stylistic set 2021-02-08 19:43:05 +01:00
Vitaly Provodin
41de3a4cb1 JBR-3064 Disable AllowEnhancedClassRedefinition in flight recorder 2021-02-08 16:35:14 +07:00
Dmitry Batrak
304eb7f919 make AwtListGarbageCollectionTest pass reliably 2021-02-08 12:22:09 +03:00
Ivan Migalev
442bb7eecc JBR-3068 Update path selector behavior when sun.awt.windows.useCommonItemDialog is enabled 2021-02-08 12:00:28 +03:00
Dmitry Batrak
09941119e1 JBR-3017 Focus issue in presence of third-party accessibility tool
Guard against possible deadlocks, if UI-related methods are invoked not on EDT.
Sample deadlock scenario:
* Application thread attempts to show the window, this involves calling CWrapper.NSWindow.makeKeyAndOrderFront under AWT tree lock, which blocks till 'makeKeyAndOrderFront' completes on AppKit thread
* AppKit thread, while executing 'makeKeyAndOrderFront' performs 'back-call' to CAccessibility.getFocusOwner, which waits for execution on EDT
* EDT performs some activity requiring AWT tree lock (e.g. processing of PaintEvent)
2021-02-05 19:46:17 +03:00
Dmitry Batrak
e3aaff5db4 JBR-3017 Focus issue in presence of third-party accessibility tool
use the new invocation approach for 'makeKeyAndOrderFront' as well, as it can also cause synchronous back-calls to accessibility subsystem, and change the global call order unexpectedly

this commit fixes TypeaheadSetVisibleTest and TypeaheadToFrontTest, when they are run with AltTab active
2021-02-05 19:46:16 +03:00
Dmitry Batrak
99242748ee JBR-3072 Deadlock on nested dialog hiding 2021-02-04 14:14:01 +03:00
Vitaly Provodin
c1f4b0ca72 JBR-2124 remove JavaFX from JBR 2021-02-04 07:08:36 +07:00
Alexey Ushakov
553e5ca631 JBR-3066 jbr 11_10 (1145-88) crashes on IDEA startup, jbr 11_09 (1145-77) works fine
Renamed bundled harfbuzz with a new name (jharfbuzz) to use only inside libfontmanager.
2021-02-03 09:02:49 -08:00
Dmitry Batrak
aee4b48d20 JBR-3071 Remove naming workaround for Fira Code 2021-02-03 13:08:03 +03:00
Mikhail Grishchenko
bef85f8cea updated JTreg exclude list 2021-02-03 16:20:09 +07:00
Dmitry Batrak
0161050077 JBR-1752 Floating windows overlap modal dialogs 2021-02-01 17:00:13 +03:00
Denis Konoplev
a7c8b0b535 JBR-1995: Last character issue with korean
Fix for JTextComponent
2021-01-29 18:18:28 +03:00
Alexey Ushakov
985a1c8426 JBR-3023 Gray idea frame after project open with ide.mac.transparentTitleBarAppearance.
Set styleBits default values for WINDOW_TRANSPARENT_TITLEBAR_APPEARANCE property
2021-01-28 22:08:25 +03:00
Konstantin Bulenkov
2106b67380 Merge pull request #51 from JetBrains/mono/2.225
JetBrains Mono release 2.225
2021-01-27 14:51:07 +01:00
Prasanta Sadhukhan
58493967cd 8257242: [macOS] Java app crashes while switching input methods
Reviewed-by: serb
(cherry picked from commit 706d936ebe)
2021-01-27 19:01:43 +07:00
Prasanta Sadhukhan
2c82032f4c 8248532: Every time I change keyboard language at my MacBook, Java crashes
Reviewed-by: serb, prr
(cherry picked from commit 532775249f)
2021-01-27 19:01:32 +07:00
Vitaly Provodin
c571f300c6 Revert "JBR-2340 Frequent IDEA 2020.2 crashes on macOS"
This reverts commit 08f9ba66
2021-01-27 19:01:15 +07:00
Vitaly Provodin
9d8b89962f merge DCEVM patches with update_11.0.10 2021-01-27 19:00:48 +07:00
Vitaly Provodin
af014f4c2d Merge branch 'update_11.0.10' 2021-01-27 19:00:25 +07:00
MonoBot
b1c1b24890 Fonts release 2.225 2021-01-27 14:23:44 +03:00
Dmitry Batrak
0c2b6e1c04 JBR-3054 Focus is not returned to frame after closing of second-level popup on Windows 2021-01-27 11:19:58 +03:00
162 changed files with 4025 additions and 3049 deletions

View File

@@ -1,9 +1,7 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright 2000-&amp;#36;today.year JetBrains s.r.o.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
<option name="keyword" value="Copyright" />
<option name="allowReplaceKeyword" value="JetBrains" />
<option name="allowReplaceRegexp" value="JetBrains" />
<option name="notice" value="Copyright 2000-&amp;#36;today.year JetBrains s.r.o.&#10;DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.&#10; &#10;This code is free software; you can redistribute it and/or modify it&#10;under the terms of the GNU General Public License version 2 only, as&#10;published by the Free Software Foundation.&#10;&#10;This code is distributed in the hope that it will be useful, but WITHOUT&#10;ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or&#10;FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License&#10;version 2 for more details (a copy is included in the LICENSE file that&#10;accompanied this code).&#10;&#10;You should have received a copy of the GNU General Public License version&#10;2 along with this work; if not, write to the Free Software Foundation,&#10;Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.&#10;&#10;Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA&#10;or visit www.oracle.com if you need additional information or have any&#10;questions." />
<option name="myName" value="JetBrains" />
<option name="myLocal" value="true" />
</copyright>
</component>

View File

@@ -1,12 +1,5 @@
[![official JetBrains project](http://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
# Downloads
|Windows-x64 |macOS |Linux-x64 |
|-------------|-------------|-------------|
|[ ![Download](https://api.bintray.com/packages/jetbrains/intellij-jdk/openjdk11-windows-x64/images/download.svg) ](https://bintray.com/jetbrains/intellij-jdk/openjdk11-windows-x64/_latestVersion)|[ ![Download](https://api.bintray.com/packages/jetbrains/intellij-jdk/openjdk11-osx-x64/images/download.svg) ](https://bintray.com/jetbrains/intellij-jdk/openjdk11-osx-x64/_latestVersion)|[ ![Download](https://api.bintray.com/packages/jetbrains/intellij-jdk/openjdk11-linux-x64/images/download.svg) ](https://bintray.com/jetbrains/intellij-jdk/openjdk11-linux-x64/_latestVersion)|
# How JetBrains Runtime is organised
## Workspaces

View File

@@ -4,9 +4,9 @@ RUN yum -y install centos-release-scl
RUN yum -y install devtoolset-8
RUN yum -y install zip bzip2 unzip tar wget make autoconf automake libtool alsa-devel cups-devel xorg-x11-devel libjpeg62-devel giflib-devel freetype-devel file which libXtst-devel libXt-devel libXrender-devel alsa-lib-devel fontconfig-devel libXrandr-devel libXi-devel git
# Install Java 11
RUN wget https://bintray.com/jetbrains/intellij-jbr/download_file?file_path=jbrsdk-11_0_3-linux-x64-b360.2.tar.gz \
RUN wget https://cdn.azul.com/zulu/bin/zulu11.45.27-ca-jdk11.0.10-linux_x64.tar.gz \
-O - | tar xz -C /
ENV JAVA_HOME /jbrsdk
ENV JAVA_HOME /zulu11.45.27-ca-jdk11.0.10-linux_x64
ENV PATH $JAVA_HOME/bin:/opt/rh/devtoolset-8/root/usr/bin:$PATH
RUN git config --global user.email "teamcity@buildserver.intellij.net"
RUN git config --global user.name "builduser"

View File

@@ -6,7 +6,6 @@
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz

View File

@@ -6,8 +6,6 @@
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to be built; possible values:
# jcef - the release bundles with jcef
# jfx - the release bundles with javafx
# jcef_jfx - the release bundles with jcef and javafx
# dcevm - the release bundles with dcevm patches
# nomod - the release bundles without any additional modules (jcef)
# fd - the fastdebug bundles which also include the jcef module
@@ -41,12 +39,9 @@ function create_jbr {
JBR_BUNDLE=jbr_${bundle_type}
case "${bundle_type}" in
"jfx" | "jcef" | "dcevm" | "nomod" | "fd")
"jcef" | "dcevm" | "nomod" | "fd")
JBR_BASE_NAME=jbr_${bundle_type}-${JBSDK_VERSION}
;;
"jfx_jcef")
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
;;
*)
echo "***ERR*** bundle was not specified" && do_exit 1
;;
@@ -80,19 +75,10 @@ WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=linux-x86_64-normal-server-release
JBSDK=${JBRSDK_BASE_NAME}-linux-x64-b${build_number}
case "$bundle_type" in
"jfx")
git apply -p0 < jb/project/tools/patches/add_jfx_module.patch || do_exit $?
do_reset_changes=1
;;
"jcef")
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
do_reset_changes=1
;;
"jfx_jcef")
git apply -p0 < jb/project/tools/patches/add_jfx_module.patch || do_exit $?
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
do_reset_changes=1
;;
"dcevm")
HEAD_REVISION=$(git rev-parse HEAD)
git am jb/project/tools/patches/dcevm/*.patch || do_exit $?

View File

@@ -6,7 +6,6 @@
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz

View File

@@ -6,8 +6,6 @@
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to be built; possible values:
# jcef - the release bundles with jcef
# jfx - the release bundles with javafx
# jcef_jfx - the release bundles with jcef and javafx
# dcevm - the release bundles with dcevm patches
# nomod - the release bundles without any additional modules (jcef)
# fd - the fastdebug bundles which also include the jcef module
@@ -41,27 +39,17 @@ source jb/project/tools/common.sh
function copyJNF {
__contents_dir=$1
# we can't notarize this library as usual framework (with headers and tbd-file)
# but single library notarizes correctly
mkdir -p ${__contents_dir}/Frameworks/JavaNativeFoundation.framework/Resources
cp -p Frameworks/JavaNativeFoundation.framework/JavaNativeFoundation \
${__contents_dir}/Frameworks/JavaNativeFoundation.framework || do_exit $?
cp -p Frameworks/JavaNativeFoundation.framework/Resources/Info.plist \
${__contents_dir}/Frameworks/JavaNativeFoundation.framework/Resources || do_exit $?
# unsign JavaNativeFoundation binary (otherwise notarization will fail)
codesign --remove-signature ${__contents_dir}/Frameworks/JavaNativeFoundation.framework/JavaNativeFoundation || do_exit $?
mkdir -p ${__contents_dir}/Frameworks
cp -Rp Frameworks/JavaNativeFoundation.framework ${__contents_dir}/Frameworks
}
function create_jbr {
JBR_BUNDLE=jbr_${bundle_type}
case "${bundle_type}" in
"jfx" | "jcef" | "dcevm" | "nomod" | "fd")
"jcef" | "dcevm" | "nomod" | "fd")
JBR_BASE_NAME=jbr_${bundle_type}-${JBSDK_VERSION}
;;
"jfx_jcef")
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
;;
*)
echo "***ERR*** bundle was not specified" && do_exit 1
;;
@@ -122,19 +110,10 @@ CONF_NAME=macosx-${CONF_ARCHITECTURE}-normal-server-release
JBSDK=${JBRSDK_BASE_NAME}-osx-${architecture}-b${build_number}
case "$bundle_type" in
"jfx")
git apply -p0 < jb/project/tools/patches/add_jfx_module.patch || do_exit $?
do_reset_changes=1
;;
"jcef")
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
do_reset_changes=1
;;
"jfx_jcef")
git apply -p0 < jb/project/tools/patches/add_jfx_module.patch || do_exit $?
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
do_reset_changes=1
;;
"dcevm")
HEAD_REVISION=$(git rev-parse HEAD)
git am jb/project/tools/patches/dcevm/*.patch || do_exit $?

View File

@@ -26,8 +26,7 @@ log "Signing libraries and executables..."
# -perm +111 searches for executables
for f in \
"Contents/Home/bin" \
"Contents/Home/lib" \
"Contents/Frameworks"; do
"Contents/Home/lib"; do
if [ -d "$APP_DIRECTORY/$f" ]; then
find "$APP_DIRECTORY/$f" \
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -perm +111 \) \
@@ -37,6 +36,20 @@ for f in \
fi
done
if [ -d "$APP_DIRECTORY/Contents/Frameworks" ]; then
log "Signing frameworks..."
for f in $APP_DIRECTORY/Contents/Frameworks/*; do
find "$f" \
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" \) \
-exec codesign --timestamp --force \
-v -s "$JB_CERT" \
--entitlements entitlements.xml {} \;
codesign --timestamp --force \
-v -s "$JB_CERT" --options=runtime \
--entitlements entitlements.xml "$f"
done
fi
log "Signing libraries in jars in $PWD"
# todo: add set -euo pipefail; into the inner sh -c

View File

@@ -1,18 +1,18 @@
diff --git modules.list modules.list
index e23d793..368d022 100644
index 33375b527c4..76539cbc0e0 100644
--- modules.list
+++ modules.list
@@ -54,4 +54,7 @@ jdk.security.jgss,
jdk.unsupported,
@@ -55,4 +55,7 @@ jdk.unsupported,
jdk.xml.dom,
jdk.zipfs,
-jdk.hotspot.agent
+jdk.hotspot.agent,
jdk.hotspot.agent,
-jdk.jcmd
+jdk.jcmd,
+jcef,
+gluegen.rt,
+jogl.all
diff --git src/java.desktop/share/classes/module-info.java src/java.desktop/share/classes/module-info.java
index b663b38..3e9acdc 100644
index b663b382f52..3e9acdc0c27 100644
--- src/java.desktop/share/classes/module-info.java
+++ src/java.desktop/share/classes/module-info.java
@@ -109,7 +109,11 @@ module java.desktop {

View File

@@ -1,18 +0,0 @@
diff --git modules.list modules.list
index e23d793ca61..14b9a6c8e50 100644
--- modules.list
+++ modules.list
@@ -20,6 +20,13 @@ java.sql.rowset,
java.transaction.xa,
java.xml,
java.xml.crypto,
+javafx.base,
+javafx.controls,
+javafx.fxml,
+javafx.graphics,
+javafx.media,
+javafx.swing,
+javafx.web,
jdk.accessibility,
jdk.aot,
jdk.attach,

View File

@@ -0,0 +1,31 @@
From 62fc66fa74886bd8bb15cd3e2084175f7ad5d0c7 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Fri, 5 Feb 2021 23:30:49 +0100
Subject: [PATCH 19/19] Disable AllowEnhancedClassRedefinition in flight
recorder
---
src/hotspot/share/runtime/arguments.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index 5053ad7ee61..c5635bb8537 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -3962,6 +3962,13 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
// Set object alignment values.
set_object_alignment();
+ if (FlightRecorder) {
+ if (AllowEnhancedClassRedefinition) {
+ warning("EnhancedClassRedefinition was disabled, it is not allowed in FlightRecorder.");
+ AllowEnhancedClassRedefinition = false;
+ }
+ }
+
setup_hotswap_agent();
#if !INCLUDE_CDS
--
2.23.0

View File

@@ -6,8 +6,6 @@
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to be built; possible values:
# jcef - the release bundles with jcef
# jfx - the release bundles with javafx
# jcef_jfx - the release bundles with jcef and javafx
# dcevm - the release bundles with dcevm patches
# nomod - the release bundles without any additional modules (jcef)
# fd - the fastdebug bundles which also include the jcef module
@@ -43,12 +41,9 @@ function create_jbr {
JBR_BUNDLE=jbr_${bundle_type}
case "${bundle_type}" in
"jfx" | "jcef" | "dcevm" | "nomod" | "fd")
"jcef" | "dcevm" | "nomod" | "fd")
JBR_BASE_NAME=jbr_${bundle_type}-${JBSDK_VERSION}
;;
"jfx_jcef")
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
;;
*)
echo "***ERR*** bundle was not specified" && do_exit 1
;;
@@ -73,19 +68,10 @@ WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=windows-x86_64-normal-server-release
JBSDK=${JBRSDK_BASE_NAME}-windows-x64-b${build_number}
case "$bundle_type" in
"jfx")
git apply -p0 < jb/project/tools/patches/add_jfx_module.patch || do_exit $?
do_reset_changes=1
;;
"jcef")
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
do_reset_changes=1
;;
"jfx_jcef")
git apply -p0 < jb/project/tools/patches/add_jfx_module.patch || do_exit $?
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
do_reset_changes=1
;;
"dcevm")
HEAD_REVISION=$(git rev-parse HEAD)
git am jb/project/tools/patches/dcevm/*.patch || do_exit $?

View File

@@ -6,7 +6,6 @@
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz

View File

@@ -6,8 +6,6 @@
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to be built; possible values:
# jcef - the release bundles with jcef
# jfx - the release bundles with javafx
# jcef_jfx - the release bundles with jcef and javafx
# dcevm - the release bundles with dcevm patches
# nomod - the release bundles without any additional modules (jcef)
# fd - the fastdebug bundles which also include the jcef module
@@ -38,12 +36,9 @@ function pack_jbr {
JBR_BUNDLE=jbr_${bundle_type}
case "${bundle_type}" in
"jfx" | "jcef" | "dcevm" | "nomod" | "fd")
"jcef" | "dcevm" | "nomod" | "fd")
JBR_BASE_NAME=jbr_${bundle_type}-${JBSDK_VERSION}
;;
"jfx_jcef")
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
;;
*)
echo "***ERR*** bundle was not specified" && do_exit 1
;;

View File

@@ -6,7 +6,6 @@
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz

View File

@@ -572,98 +572,36 @@ endif
###########################################################################
ifeq ($(USE_EXTERNAL_HARFBUZZ), true)
LIBHARFBUZZ_LIBS := $(HARFBUZZ_LIBS)
LIBFONTMANAGER_EXTRA_SRC =
BUILD_LIBFONTMANAGER_FONTLIB += $(LIBHARFBUZZ_LIBS)
else
HARFBUZZ_CFLAGS := -DHAVE_OT -DHAVE_FALLBACK -DHAVE_UCDN -DHAVE_ROUND
# This is better than adding EXPORT_ALL_SYMBOLS
ifneq ($(filter $(TOOLCHAIN_TYPE), gcc clang solstudio), )
HARFBUZZ_CFLAGS += -DHB_EXTERN=__attribute__\(\(visibility\(\"default\"\)\)\)
else ifeq ($(TOOLCHAIN_TYPE), microsoft)
HARFBUZZ_CFLAGS += -DHB_EXTERN=__declspec\(dllexport\)
endif
LIBFONTMANAGER_EXTRA_SRC = libharfbuzz
HARFBUZZ_CFLAGS := -DHAVE_OT -DHAVE_FALLBACK -DHAVE_UCDN -DHAVE_ROUND
ifneq ($(OPENJDK_TARGET_OS), windows)
HARFBUZZ_CFLAGS += -DGETPAGESIZE -DHAVE_MPROTECT -DHAVE_PTHREAD \
-DHAVE_SYSCONF -DHAVE_SYS_MMAN_H -DHAVE_UNISTD_H \
-DHB_NO_PRAGMA_GCC_DIAGNOSTIC
endif
ifneq (, $(findstring $(OPENJDK_TARGET_OS), linux macosx))
HARFBUZZ_CFLAGS += -DHAVE_INTEL_ATOMIC_PRIMITIVES
endif
LIBHARFBUZZ_LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN)
ifeq ($(TOOLCHAIN_TYPE), gcc)
ifeq ($(CC_VERSION_NUMBER), 4.4.7)
LIBHARFBUZZ_LDFLAGS := $(subst -Xlinker -z -Xlinker defs,, \
$(subst -Wl$(COMMA)-z$(COMMA)defs,,$(LDFLAGS_JDKLIB))) \
$(call SET_SHARED_LIBRARY_ORIGIN)
endif
endif
# hb-ft.cc is not presently needed, and requires freetype 2.4.2 or later.
LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-ft.cc \
libharfbuzz/hb-coretext.cc
ifneq ($(OPENJDK_TARGET_OS), windows)
HARFBUZZ_CFLAGS += -DGETPAGESIZE -DHAVE_MPROTECT -DHAVE_PTHREAD \
-DHAVE_SYSCONF -DHAVE_SYS_MMAN_H -DHAVE_UNISTD_H \
-DHB_NO_PRAGMA_GCC_DIAGNOSTIC
endif
ifneq (, $(findstring $(OPENJDK_TARGET_OS), linux macosx))
HARFBUZZ_CFLAGS += -DHAVE_INTEL_ATOMIC_PRIMITIVES
endif
ifeq ($(OPENJDK_TARGET_OS), solaris)
HARFBUZZ_CFLAGS += -DHAVE_SOLARIS_ATOMIC_OPS
endif
HARFBUZZ_EXTRA_HEADER_DIRS := \
libharfbuzz/hb-ucdn
LIBHARFBUZZ_EXCLUDE_FILES += harfbuzz/hb-coretext.cc
HARFBUZZ_DISABLED_WARNINGS_gcc := type-limits missing-field-initializers strict-aliasing
HARFBUZZ_DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \
maybe-uninitialized class-memaccess
HARFBUZZ_DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \
tautological-constant-out-of-range-compare int-to-pointer-cast \
undef missing-field-initializers range-loop-analysis
HARFBUZZ_DISABLED_WARNINGS_microsoft := 4267 4244 4090 4146 4334 4819 4101 4068 4805 4138
# hb-ft.cc is not presently needed, and requires freetype 2.4.2 or later.
LIBHARFBUZZ_EXCLUDE_FILES += harfbuzz/hb-ft.cc
LIBHARFBUZZ_CFLAGS += $(HARFBUZZ_CFLAGS)
# For use by libfontmanager:
ifeq ($(OPENJDK_TARGET_OS), windows)
LIBHARFBUZZ_LIBS := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libharfbuzz/harfbuzz.lib
else
LIBHARFBUZZ_LIBS := -lharfbuzz
endif
LIBHARFBUZZ_EXTRA_HEADER_DIRS := \
libharfbuzz/hb-ucdn \
#
LIBHARFBUZZ_OPTIMIZATION := HIGH
LIBHARFBUZZ_CFLAGS += $(X_CFLAGS) -DLE_STANDALONE -DHEADLESS
$(eval $(call SetupJdkLibrary, BUILD_LIBHARFBUZZ, \
NAME := harfbuzz, \
EXCLUDE_FILES := $(LIBHARFBUZZ_EXCLUDE_FILES), \
TOOLCHAIN := TOOLCHAIN_LINK_CXX, \
CFLAGS := $(CFLAGS_JDKLIB) $(LIBHARFBUZZ_CFLAGS), \
CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBHARFBUZZ_CFLAGS), \
OPTIMIZATION := $(LIBHARFBUZZ_OPTIMIZATION), \
CFLAGS_windows = -DCC_NOEX, \
EXTRA_HEADER_DIRS := $(LIBHARFBUZZ_EXTRA_HEADER_DIRS), \
WARNINGS_AS_ERRORS_xlc := false, \
DISABLED_WARNINGS_gcc := type-limits missing-field-initializers strict-aliasing, \
DISABLED_WARNINGS_CXX_gcc := reorder delete-non-virtual-dtor strict-overflow \
maybe-uninitialized class-memaccess, \
DISABLED_WARNINGS_clang := unused-value incompatible-pointer-types \
tautological-constant-out-of-range-compare int-to-pointer-cast \
undef missing-field-initializers, \
DISABLED_WARNINGS_C_solstudio := \
E_INTEGER_OVERFLOW_DETECTED \
E_ARG_INCOMPATIBLE_WITH_ARG_L \
E_ENUM_VAL_OVERFLOWS_INT_MAX, \
DISABLED_WARNINGS_CXX_solstudio := \
truncwarn wvarhidenmem wvarhidemem wbadlkginit identexpected \
hidevf w_novirtualdescr arrowrtn2 unknownpragma, \
DISABLED_WARNINGS_microsoft := 4267 4244 4090 4146 4334 4819 4101 4068 4805 4138, \
LDFLAGS := $(LIBHARFBUZZ_LDFLAGS), \
LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \
LDFLAGS_aix := -Wl$(COMMA)-berok, \
LIBS := $(BUILD_LIBHARFBUZZ), \
LIBS_unix := $(LIBM) $(LIBCXX), \
LIBS_macosx := -framework CoreText -framework CoreFoundation -framework CoreGraphics, \
LIBS_windows := user32.lib, \
))
ifeq ($(FREETYPE_TO_USE), bundled)
$(BUILD_LIBHARFBUZZ): $(BUILD_LIBFREETYPE)
endif
TARGETS += $(BUILD_LIBHARFBUZZ)
LIBFONTMANAGER_CFLAGS += $(HARFBUZZ_CFLAGS)
endif
@@ -678,10 +616,10 @@ LIBFONTMANAGER_EXTRA_HEADER_DIRS := \
libawt/java2d/loops \
#
LIBFONTMANAGER_CFLAGS += $(LIBFREETYPE_CFLAGS) $(HARFBUZZ_FLAGS)
BUILD_LIBFONTMANAGER_FONTLIB += $(LIBHARFBUZZ_LIBS) $(LIBFREETYPE_LIBS)
LIBFONTMANAGER_CFLAGS += $(LIBFREETYPE_CFLAGS)
BUILD_LIBFONTMANAGER_FONTLIB += $(LIBFREETYPE_LIBS)
LIBFONTMANAGER_OPTIMIZATION := HIGH
LIBFONTMANAGER_OPTIMIZATION := HIGHEST
ifeq ($(OPENJDK_TARGET_OS), windows)
LIBFONTMANAGER_EXCLUDE_FILES += X11FontScaler.c \
@@ -720,18 +658,13 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBFONTMANAGER, \
CXXFLAGS := $(CXXFLAGS_JDKLIB) $(LIBFONTMANAGER_CFLAGS), \
OPTIMIZATION := $(LIBFONTMANAGER_OPTIMIZATION), \
CFLAGS_windows = -DCC_NOEX, \
EXTRA_HEADER_DIRS := $(LIBFONTMANAGER_EXTRA_HEADER_DIRS), \
EXTRA_HEADER_DIRS := $(LIBFONTMANAGER_EXTRA_HEADER_DIRS) $(HARFBUZZ_EXTRA_HEADER_DIRS), \
EXTRA_SRC := $(LIBFONTMANAGER_EXTRA_SRC), \
WARNINGS_AS_ERRORS_xlc := false, \
DISABLED_WARNINGS_gcc := sign-compare unused-function int-to-pointer-cast, \
DISABLED_WARNINGS_clang := sign-compare, \
DISABLED_WARNINGS_C_solstudio := \
E_INTEGER_OVERFLOW_DETECTED \
E_ARG_INCOMPATIBLE_WITH_ARG_L \
E_ENUM_VAL_OVERFLOWS_INT_MAX, \
DISABLED_WARNINGS_CXX_solstudio := \
truncwarn wvarhidenmem wvarhidemem wbadlkginit identexpected \
hidevf w_novirtualdescr arrowrtn2 unknownpragma, \
DISABLED_WARNINGS_microsoft := 4018 4146 4244 4996 4996 4146 4334 4819 4101 4068 4805 4138, \
DISABLED_WARNINGS_gcc := $(HARFBUZZ_DISABLED_WARNINGS_gcc), \
DISABLED_WARNINGS_CXX_gcc := $(HARFBUZZ_DISABLED_WARNINGS_CXX_gcc), \
DISABLED_WARNINGS_clang := $(HARFBUZZ_DISABLED_WARNINGS_clang), \
DISABLED_WARNINGS_microsoft := $(HARFBUZZ_DISABLED_WARNINGS_microsoft), \
LDFLAGS := $(subst -Xlinker -z -Xlinker defs,, \
$(subst -Wl$(COMMA)-z$(COMMA)defs,,$(LDFLAGS_JDKLIB))) $(LDFLAGS_CXX_JDK) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
@@ -739,17 +672,13 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBFONTMANAGER, \
LDFLAGS_aix := -Wl$(COMMA)-berok, \
LIBS := $(BUILD_LIBFONTMANAGER_FONTLIB), \
LIBS_unix := -lawt -ljava -ljvm $(LIBM) $(LIBCXX), \
LIBS_macosx := -lawt_lwawt, \
LIBS_macosx := -lawt_lwawt -framework CoreText -framework CoreFoundation -framework CoreGraphics, \
LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib gdi32.lib \
$(WIN_AWT_LIB), \
))
$(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT)
ifeq ($(USE_EXTERNAL_HARFBUZZ), false)
$(BUILD_LIBFONTMANAGER): $(BUILD_LIBHARFBUZZ)
endif
ifeq ($(OPENJDK_TARGET_OS), macosx)
$(BUILD_LIBFONTMANAGER): $(call FindLib, $(MODULE), awt_lwawt)
endif

View File

@@ -54,4 +54,5 @@ jdk.security.jgss,
jdk.unsupported,
jdk.xml.dom,
jdk.zipfs,
jdk.hotspot.agent
jdk.hotspot.agent,
jdk.jcmd

View File

@@ -1354,6 +1354,7 @@ static int _print_module(const char* fname, address base_address,
return 0;
}
static errno_t convert_to_unicode(char const* char_path, LPWSTR* unicode_path);
// Loads .dll/.so and
// in case of error it checks if .dll/.so was built for the
// same architecture as Hotspot is running on

View File

@@ -736,16 +736,17 @@ public final class SSLSocketImpl
// Is it ready to close inbound?
//
// No need to throw exception if the initial handshake is not started.
if (checkCloseNotify && !conContext.isInputCloseNotified &&
(conContext.isNegotiated || conContext.handshakeContext != null)) {
throw conContext.fatal(Alert.INTERNAL_ERROR,
try {
if (checkCloseNotify && !conContext.isInputCloseNotified &&
(conContext.isNegotiated || conContext.handshakeContext != null)) {
throw new SSLException(
"closing inbound before receiving peer's close_notify");
}
conContext.closeInbound();
if ((autoClose || !isLayered()) && !super.isInputShutdown()) {
super.shutdownInput();
}
} finally {
conContext.closeInbound();
if ((autoClose || !isLayered()) && !super.isInputShutdown()) {
super.shutdownInput();
}
}
}

View File

@@ -211,17 +211,6 @@ ImageFileReaderTable::ImageFileReaderTable() : _count(0), _max(_growth) {
assert(_table != NULL && "allocation failed");
}
ImageFileReaderTable::~ImageFileReaderTable() {
for (u4 i = 0; i < _count; i++) {
ImageFileReader* image = _table[i];
if (image != NULL) {
delete image;
}
}
free(_table);
}
// Add a new image entry to the table.
void ImageFileReaderTable::add(ImageFileReader* image) {
if (_count == _max) {

View File

@@ -371,7 +371,12 @@ private:
public:
ImageFileReaderTable();
~ImageFileReaderTable();
// ~ImageFileReaderTable()
// Bug 8166727
//
// WARNING: Should never close jimage files.
// Threads may still be running during shutdown.
//
// Return the number of entries.
inline u4 count() { return _count; }

View File

@@ -944,9 +944,12 @@ class WindowsNativeDispatcher {
CreateSymbolicLink0(linkBuffer.address(),
targetBuffer.address(), flags);
return;
} catch (WindowsException ignored) {
} catch (WindowsException xx) {
// Will fail with ERROR_INVALID_PARAMETER for Windows
// builds older than 14972.
if (xx.lastError() != ERROR_INVALID_PARAMETER) {
x = xx;
}
}
}
throw x;

View File

@@ -1,51 +0,0 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.eawt;
import com.apple.eawt.AppEvent.AppForegroundEvent;
/**
* Implementors are notified when the app becomes the foreground app and when it resigns being the foreground app.
* This notification is useful for hiding and showing transient UI like palette windows which should be hidden when the app is in the background.
*
* @see Application#addAppEventListener(AppEventListener)
*
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
public interface AppForegroundListener extends AppEventListener {
/**
* Called when the app becomes the foreground app.
* @param e the app became foreground notification.
*/
public void appRaisedToForeground(final AppForegroundEvent e);
/**
* Called when the app resigns to the background and another app becomes the foreground app.
* @param e the app resigned foreground notification.
*/
public void appMovedToBackground(final AppForegroundEvent e);
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.eawt;
import com.apple.eawt.AppEvent.AppHiddenEvent;
/**
* Implementors are notified when the app is hidden or shown by the user.
* This notification is helpful for discontinuing a costly animation if it's not visible to the user.
*
* @see Application#addAppEventListener(AppEventListener)
*
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
public interface AppHiddenListener extends AppEventListener {
/**
* Called the app is hidden.
* @param e
*/
public void appHidden(final AppHiddenEvent e);
/**
* Called when the hidden app is shown again (but not necessarily brought to the foreground).
* @param e
*/
public void appUnhidden(final AppHiddenEvent e);
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.eawt;
import com.apple.eawt.AppEvent.AppReOpenedEvent;
/**
* Implementors receive notification when the app has been asked to open again.
* Re-open events occur when the user clicks on the running app's Dock icon.
* Re-open events also occur when the app is double-clicked in the Finder and the app is already running.
*
* This notification is useful for showing a new document when your app has no open windows.
*
* @see Application#addAppEventListener(AppEventListener)
*
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
public interface AppReOpenedListener extends AppEventListener {
/**
* Called when the app has been re-opened (it's Dock icon was clicked on, or was double-clicked in the Finder)
* @param e the request to re-open the app
*/
public void appReOpened(final AppReOpenedEvent e);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,20 +25,38 @@
package com.apple.eawt;
import java.awt.*;
import java.awt.peer.*;
import java.awt.Image;
import java.awt.PopupMenu;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.desktop.AboutHandler;
import java.awt.desktop.AppForegroundListener;
import java.awt.desktop.AppHiddenListener;
import java.awt.desktop.AppReopenedListener;
import java.awt.desktop.OpenFilesEvent;
import java.awt.desktop.OpenFilesHandler;
import java.awt.desktop.OpenURIEvent;
import java.awt.desktop.OpenURIHandler;
import java.awt.desktop.PreferencesHandler;
import java.awt.desktop.PrintFilesEvent;
import java.awt.desktop.PrintFilesHandler;
import java.awt.desktop.QuitHandler;
import java.awt.desktop.QuitResponse;
import java.awt.desktop.QuitStrategy;
import java.awt.desktop.ScreenSleepListener;
import java.awt.desktop.SystemEventListener;
import java.awt.desktop.SystemSleepListener;
import java.awt.desktop.UserSessionListener;
import java.beans.Beans;
import java.util.function.Consumer;
import javax.swing.JMenuBar;
import sun.lwawt.*;
import sun.lwawt.macosx.*;
import sun.awt.AWTAccessor;
import sun.util.logging.PlatformLogger;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.macosx.CPlatformWindow;
/**
* The <code>Application</code> class allows you to integrate your Java application with the native Mac OS X environment.
* The {@code Application} class allows you to integrate your Java application with the native Mac OS X environment.
* You can provide your Mac OS X users a greatly enhanced experience by implementing a few basic handlers for standard system events.
*
* For example:
@@ -56,22 +74,13 @@ import sun.util.logging.PlatformLogger;
* @since 1.4
*/
public class Application {
private static final PlatformLogger focusRequestLog = PlatformLogger.getLogger("jb.focus.requests");
private static native void nativeInitializeApplicationDelegate();
static Application sApplication = null;
static {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("awt");
return null;
}
});
checkSecurity();
Toolkit.getDefaultToolkit(); // Start AppKit
if (!Beans.isDesignTime()) {
nativeInitializeApplicationDelegate();
}
@@ -112,11 +121,11 @@ public class Application {
}
/**
* Adds sub-types of {@link AppEventListener} to listen for notifications from the native Mac OS X system.
* Adds sub-types of {@link SystemEventListener} to listen for notifications from the native Mac OS X system.
*
* @see AppForegroundListener
* @see AppHiddenListener
* @see AppReOpenedListener
* @see AppReopenedListener
* @see ScreenSleepListener
* @see SystemSleepListener
* @see UserSessionListener
@@ -125,16 +134,16 @@ public class Application {
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
public void addAppEventListener(final AppEventListener listener) {
public void addAppEventListener(final SystemEventListener listener) {
eventHandler.addListener(listener);
}
/**
* Removes sub-types of {@link AppEventListener} from listening for notifications from the native Mac OS X system.
* Removes sub-types of {@link SystemEventListener} from listening for notifications from the native Mac OS X system.
*
* @see AppForegroundListener
* @see AppHiddenListener
* @see AppReOpenedListener
* @see AppReopenedListener
* @see ScreenSleepListener
* @see SystemSleepListener
* @see UserSessionListener
@@ -143,16 +152,16 @@ public class Application {
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
public void removeAppEventListener(final AppEventListener listener) {
public void removeAppEventListener(final SystemEventListener listener) {
eventHandler.removeListener(listener);
}
/**
* Installs a handler to show a custom About window for your application.
*
* Setting the {@link AboutHandler} to <code>null</code> reverts it to the default Cocoa About window.
* Setting the {@link AboutHandler} to {@code null} reverts it to the default Cocoa About window.
*
* @param aboutHandler the handler to respond to the {@link AboutHandler#handleAbout()} message
* @param aboutHandler the handler to respond to the {@link AboutHandler#handleAbout} message
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
@@ -163,7 +172,7 @@ public class Application {
/**
* Installs a handler to create the Preferences menu item in your application's app menu.
*
* Setting the {@link PreferencesHandler} to <code>null</code> will remove the Preferences item from the app menu.
* Setting the {@link PreferencesHandler} to {@code null} will remove the Preferences item from the app menu.
*
* @param preferencesHandler
* @since Java for Mac OS X 10.6 Update 3
@@ -175,8 +184,8 @@ public class Application {
/**
* Installs the handler which is notified when the application is asked to open a list of files.
* The {@link OpenFilesHandler#openFiles(AppEvent.OpenFilesEvent)} notifications are only sent if the Java app is a bundled application, with a <code>CFBundleDocumentTypes</code> array present in it's Info.plist.
* See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a <code>CFBundleDocumentTypes</code> key to your app's Info.plist.
* The {@link OpenFilesHandler#openFiles(OpenFilesEvent)} notifications are only sent if the Java app is a bundled application, with a {@code CFBundleDocumentTypes} array present in it's Info.plist.
* See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a {@code CFBundleDocumentTypes} key to your app's Info.plist.
*
* @param openFileHandler
* @since Java for Mac OS X 10.6 Update 3
@@ -188,8 +197,8 @@ public class Application {
/**
* Installs the handler which is notified when the application is asked to print a list of files.
* The {@link PrintFilesHandler#printFiles(AppEvent.PrintFilesEvent)} notifications are only sent if the Java app is a bundled application, with a <code>CFBundleDocumentTypes</code> array present in it's Info.plist.
* See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a <code>CFBundleDocumentTypes</code> key to your app's Info.plist.
* The {@link PrintFilesHandler#printFiles(PrintFilesEvent)} notifications are only sent if the Java app is a bundled application, with a {@code CFBundleDocumentTypes} array present in it's Info.plist.
* See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a {@code CFBundleDocumentTypes} key to your app's Info.plist.
*
* @param printFileHandler
* @since Java for Mac OS X 10.6 Update 3
@@ -201,10 +210,10 @@ public class Application {
/**
* Installs the handler which is notified when the application is asked to open a URL.
* The {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} notifications are only sent if the Java app is a bundled application, with a <code>CFBundleURLTypes</code> array present in it's Info.plist.
* See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a <code>CFBundleURLTypes</code> key to your app's Info.plist.
* The {@link OpenURIHandler#openURI(OpenURIEvent)} notifications are only sent if the Java app is a bundled application, with a {@code CFBundleURLTypes} array present in it's Info.plist.
* See the <a href="http://developer.apple.com/mac/library/documentation/General/Reference/InfoPlistKeyReference">Info.plist Key Reference</a> for more information about adding a {@code CFBundleURLTypes} key to your app's Info.plist.
*
* Setting the handler to <code>null</code> causes all {@link OpenURIHandler#openURI(AppEvent.OpenURIEvent)} requests to be enqueued until another handler is set.
* Setting the handler to {@code null} causes all {@link OpenURIHandler#openURI(OpenURIEvent)} requests to be enqueued until another handler is set.
*
* @param openURIHandler
* @since Java for Mac OS X 10.6 Update 3
@@ -217,7 +226,7 @@ public class Application {
/**
* Installs the handler which determines if the application should quit.
* The handler is passed a one-shot {@link QuitResponse} which can cancel or proceed with the quit.
* Setting the handler to <code>null</code> causes all quit requests to directly perform the default {@link QuitStrategy}.
* Setting the handler to {@code null} causes all quit requests to directly perform the default {@link QuitStrategy}.
*
* @param quitHandler the handler that is called when the application is asked to quit
* @since Java for Mac OS X 10.6 Update 3
@@ -287,9 +296,6 @@ public class Application {
* @since Java for Mac OS X 10.5 Update 6 - 1.6, 1.5
*/
public void requestForeground(final boolean allWindows) {
if (focusRequestLog.isLoggable(PlatformLogger.Level.FINE)) {
focusRequestLog.fine("requestForeground(" + (allWindows ? "allWindows" : "") + ")", new Throwable());
}
_AppMiscHandlers.requestActivation(allWindows);
}
@@ -378,6 +384,16 @@ public class Application {
iconHandler.setDockIconBadge(badge);
}
/**
* Displays a progress bar to this application's Dock icon.
* Acceptable values are from 0 to 100, any other disables progress indication.
*
* @param value progress value
*/
public void setDockIconProgress(final int value) {
iconHandler.setDockIconProgress(value);
}
/**
* Sets the default menu bar to use when there are no active frames.
* Only used when the system property "apple.laf.useScreenMenuBar" is "true", and
@@ -400,189 +416,12 @@ public class Application {
*
* @since Java for Mac OS X 10.7 Update 1
*/
@SuppressWarnings("deprecation")
public void requestToggleFullScreen(final Window window) {
invokeOnPlatformWindow(window, pw -> pw.toggleFullScreen());
}
public void requestEnterFullScreen(final Window window) {
invokeOnPlatformWindow(window, pw -> pw.enterFullScreen());
}
public void requestLeaveFullScreen(final Window window) {
invokeOnPlatformWindow(window, pw -> pw.leaveFullScreen());
}
private void invokeOnPlatformWindow (final Window window, Consumer<CPlatformWindow> consumer) {
final Object peer = AWTAccessor.getComponentAccessor().getPeer(window);
if (!(peer instanceof LWWindowPeer)) return;
Object platformWindow = ((LWWindowPeer) peer).getPlatformWindow();
if (!(platformWindow instanceof CPlatformWindow)) return;
consumer.accept((CPlatformWindow)platformWindow);
((CPlatformWindow)platformWindow).toggleFullScreen();
}
// -- DEPRECATED API --
/**
* Adds the specified ApplicationListener as a receiver of callbacks from this class.
* This method throws a RuntimeException if the newer About, Preferences, Quit, etc handlers are installed.
*
* @param listener an implementation of ApplicationListener that handles ApplicationEvents
*
* @deprecated register individual handlers for each task (About, Preferences, Open, Print, Quit, etc)
* @since 1.4
*/
@SuppressWarnings("deprecation")
@Deprecated
public void addApplicationListener(final ApplicationListener listener) {
eventHandler.legacyHandler.addLegacyAppListener(listener);
}
/**
* Removes the specified ApplicationListener from being a receiver of callbacks from this class.
* This method throws a RuntimeException if the newer About, Preferences, Quit, etc handlers are installed.
*
* @param listener an implementation of ApplicationListener that had previously been registered to handle ApplicationEvents
*
* @deprecated unregister individual handlers for each task (About, Preferences, Open, Print, Quit, etc)
* @since 1.4
*/
@SuppressWarnings("deprecation")
@Deprecated
public void removeApplicationListener(final ApplicationListener listener) {
eventHandler.legacyHandler.removeLegacyAppListener(listener);
}
/**
* Enables the Preferences item in the application menu. The ApplicationListener receives a callback for
* selection of the Preferences item in the application menu only if this is set to <code>true</code>.
*
* If a Preferences item isn't present, this method adds and enables it.
*
* @param enable specifies whether the Preferences item in the application menu should be enabled (<code>true</code>) or not (<code>false</code>)
*
* @deprecated no replacement
* @since 1.4
*/
@Deprecated
public void setEnabledPreferencesMenu(final boolean enable) {
menuBarHandler.setPreferencesMenuItemVisible(true);
menuBarHandler.setPreferencesMenuItemEnabled(enable);
}
/**
* Enables the About item in the application menu. The ApplicationListener receives a callback for
* selection of the About item in the application menu only if this is set to <code>true</code>. Because AWT supplies
* a standard About window when an application may not, by default this is set to <code>true</code>.
*
* If the About item isn't present, this method adds and enables it.
*
* @param enable specifies whether the About item in the application menu should be enabled (<code>true</code>) or not (<code>false</code>)
*
* @deprecated no replacement
* @since 1.4
*/
@Deprecated
public void setEnabledAboutMenu(final boolean enable) {
menuBarHandler.setAboutMenuItemEnabled(enable);
}
/**
* Determines if the Preferences item of the application menu is enabled.
*
* @deprecated no replacement
* @since 1.4
*/
@Deprecated
public boolean getEnabledPreferencesMenu() {
return menuBarHandler.isPreferencesMenuItemEnabled();
}
/**
* Determines if the About item of the application menu is enabled.
*
* @deprecated no replacement
* @since 1.4
*/
@Deprecated
public boolean getEnabledAboutMenu() {
return menuBarHandler.isAboutMenuItemEnabled();
}
/**
* Determines if the About item of the application menu is present.
*
* @deprecated no replacement
* @since 1.4
*/
@Deprecated
public boolean isAboutMenuItemPresent() {
return menuBarHandler.isAboutMenuItemVisible();
}
/**
* Adds the About item to the application menu if the item is not already present.
*
* @deprecated use {@link #setAboutHandler(AboutHandler)} with a non-null {@link AboutHandler} parameter
* @since 1.4
*/
@Deprecated
public void addAboutMenuItem() {
menuBarHandler.setAboutMenuItemVisible(true);
}
/**
* Removes the About item from the application menu if the item is present.
*
* @deprecated use {@link #setAboutHandler(AboutHandler)} with a null parameter
* @since 1.4
*/
@Deprecated
public void removeAboutMenuItem() {
menuBarHandler.setAboutMenuItemVisible(false);
}
/**
* Determines if the About Preferences of the application menu is present. By default there is no Preferences menu item.
*
* @deprecated no replacement
* @since 1.4
*/
@Deprecated
public boolean isPreferencesMenuItemPresent() {
return menuBarHandler.isPreferencesMenuItemVisible();
}
/**
* Adds the Preferences item to the application menu if the item is not already present.
*
* @deprecated use {@link #setPreferencesHandler(PreferencesHandler)} with a non-null {@link PreferencesHandler} parameter
* @since 1.4
*/
@Deprecated
public void addPreferencesMenuItem() {
menuBarHandler.setPreferencesMenuItemVisible(true);
}
/**
* Removes the Preferences item from the application menu if that item is present.
*
* @deprecated use {@link #setPreferencesHandler(PreferencesHandler)} with a null parameter
* @since 1.4
*/
@Deprecated
public void removePreferencesMenuItem() {
menuBarHandler.setPreferencesMenuItemVisible(false);
}
/**
* @deprecated Use <code>java.awt.MouseInfo.getPointerInfo().getLocation()</code>.
*
* @since 1.4
*/
@Deprecated
public static Point getMouseLocationOnScreen() {
return java.awt.MouseInfo.getPointerInfo().getLocation();
}
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.eawt;
/**
* An abstract adapter class for receiving <code>ApplicationEvents</code>.
*
* ApplicationEvents are deprecated. Use individual app event listeners or handlers instead.
*
* @see Application#addAppEventListener(AppEventListener)
*
* @see AboutHandler
* @see PreferencesHandler
* @see OpenURIHandler
* @see OpenFilesHandler
* @see PrintFilesHandler
* @see QuitHandler
*
* @see AppReOpenedListener
* @see AppForegroundListener
* @see AppHiddenListener
* @see UserSessionListener
* @see ScreenSleepListener
* @see SystemSleepListener
*
* @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link QuitResponse}.
* @since 1.4
*/
@SuppressWarnings("deprecation")
@Deprecated
public class ApplicationAdapter implements ApplicationListener {
@Deprecated
public void handleAbout(final ApplicationEvent event) { }
@Deprecated
public void handleOpenApplication(final ApplicationEvent event) { }
@Deprecated
public void handleOpenFile(final ApplicationEvent event) { }
@Deprecated
public void handlePreferences(final ApplicationEvent event) { }
@Deprecated
public void handlePrintFile(final ApplicationEvent event) { }
@Deprecated
public void handleQuit(final ApplicationEvent event) { }
@Deprecated
public void handleReOpenApplication(final ApplicationEvent event) { }
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.eawt;
import java.util.EventObject;
/**
* The class of events sent to the deprecated ApplicationListener callbacks.
*
* @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link QuitResponse}
* @since 1.4
*/
@Deprecated
public class ApplicationEvent extends EventObject {
private String fFilename = null;
private boolean fHandled = false;
ApplicationEvent(final Object source) {
super(source);
}
ApplicationEvent(final Object source, final String filename) {
super(source);
fFilename = filename;
}
/**
* Determines whether an ApplicationListener has acted on a particular event.
* An event is marked as having been handled with <code>setHandled(true)</code>.
*
* @return <code>true</code> if the event has been handled, otherwise <code>false</code>
*
* @since 1.4
* @deprecated
*/
@Deprecated
public boolean isHandled() {
return fHandled;
}
/**
* Marks the event as handled.
* After this method handles an ApplicationEvent, it may be useful to specify that it has been handled.
* This is usually used in conjunction with <code>getHandled()</code>.
* Set to <code>true</code> to designate that this event has been handled. By default it is <code>false</code>.
*
* @param state <code>true</code> if the event has been handled, otherwise <code>false</code>.
*
* @since 1.4
* @deprecated
*/
@Deprecated
public void setHandled(final boolean state) {
fHandled = state;
}
/**
* Provides the filename associated with a particular AppleEvent.
* When the ApplicationEvent corresponds to an AppleEvent that needs to act on a particular file, the ApplicationEvent carries the name of the specific file with it.
* For example, the Print and Open events refer to specific files.
* For these cases, this returns the appropriate file name.
*
* @return the full path to the file associated with the event, if applicable, otherwise <code>null</code>
*
* @since 1.4
* @deprecated use {@link OpenFilesHandler} or {@link PrintFilesHandler} instead
*/
@Deprecated
public String getFilename() {
return fFilename;
}
}

View File

@@ -1,153 +0,0 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.eawt;
import java.util.EventListener;
/**
* ApplicationEvents are deprecated. Use individual AppEvent listeners or handlers instead.
*
* @see Application#addAppEventListener(AppEventListener)
*
* @see AboutHandler
* @see PreferencesHandler
* @see OpenURIHandler
* @see OpenFilesHandler
* @see PrintFilesHandler
* @see QuitHandler
*
* @see AppReOpenedListener
* @see AppForegroundListener
* @see AppHiddenListener
* @see UserSessionListener
* @see ScreenSleepListener
* @see SystemSleepListener
*
* @since 1.4
* @deprecated replaced by {@link AboutHandler}, {@link PreferencesHandler}, {@link AppReOpenedListener}, {@link OpenFilesHandler}, {@link PrintFilesHandler}, {@link QuitHandler}, {@link QuitResponse}
*/
@SuppressWarnings("deprecation")
@Deprecated
public interface ApplicationListener extends EventListener {
/**
* Called when the user selects the About item in the application menu. If <code>event</code> is not handled by
* setting <code>isHandled(true)</code>, a default About window consisting of the application's name and icon is
* displayed. To display a custom About window, designate the <code>event</code> as being handled and display the
* appropriate About window.
*
* @param event an ApplicationEvent initiated by the user choosing About in the application menu
* @deprecated use {@link AboutHandler}
*/
@Deprecated
public void handleAbout(ApplicationEvent event);
/**
* Called when the application receives an Open Application event from the Finder or another application. Usually
* this will come from the Finder when a user double-clicks your application icon. If there is any special code
* that you want to run when you user launches your application from the Finder or by sending an Open Application
* event from another application, include that code as part of this handler. The Open Application event is sent
* after AWT has been loaded.
*
* @param event the Open Application event
* @deprecated no replacement
*/
@Deprecated
public void handleOpenApplication(ApplicationEvent event);
/**
* Called when the application receives an Open Document event from the Finder or another application. This event
* is generated when a user double-clicks a document in the Finder. If the document is registered as belonging
* to your application, this event is sent to your application. Documents are bound to a particular application based
* primarily on their suffix. In the Finder, a user selects a document and then from the File Menu chooses Get Info.
* The Info window allows users to bind a document to a particular application.
*
* These events are sent only if the bound application has file types listed in the Info.plist entries Document Types
* or CFBundleDocumentTypes.
*
* The ApplicationEvent sent to this handler holds a reference to the file being opened.
*
* @param event an Open Document event with reference to the file to be opened
* @deprecated use {@link OpenFilesHandler}
*/
@Deprecated
public void handleOpenFile(ApplicationEvent event);
/**
* Called when the Preference item in the application menu is selected. Native Mac OS X applications make their
* Preferences window available through the application menu. Java applications are automatically given an application
* menu in Mac OS X. By default, the Preferences item is disabled in that menu. If you are deploying an application
* on Mac OS X, you should enable the preferences item with <code>setEnabledPreferencesMenu(true)</code> in the
* Application object and then display your Preferences window in this handler.
*
* @param event triggered when the user selects Preferences from the application menu
* @deprecated use {@link PreferencesHandler}
*/
@Deprecated
public void handlePreferences(ApplicationEvent event);
/**
* Called when the application is sent a request to print a particular file or files. You can allow other applications to
* print files with your application by implementing this handler. If another application sends a Print Event along
* with the name of a file that your application knows how to process, you can use this handler to determine what to
* do with that request. You might open your entire application, or just invoke your printing classes.
*
* These events are sent only if the bound application has file types listed in the Info.plist entries Document Types
* or CFBundleDocumentTypes.
*
* The ApplicationEvent sent to this handler holds a reference to the file being opened.
*
* @param event a Print Document event with a reference to the file(s) to be printed
* @deprecated use {@link PrintFilesHandler}
*/
@Deprecated
public void handlePrintFile(ApplicationEvent event);
/**
* Called when the application is sent the Quit event. This event is generated when the user selects Quit from the
* application menu, when the user types Command-Q, or when the user control clicks on your application icon in the
* Dock and chooses Quit. You can either accept or reject the request to quit. You might want to reject the request
* to quit if the user has unsaved work. Reject the request, move into your code to save changes, then quit your
* application. To accept the request to quit, and terminate the application, set <code>isHandled(true)</code> for the
* <code>event</code>. To reject the quit, set <code>isHandled(false)</code>.
*
* @param event a Quit Application event
* @deprecated use {@link QuitHandler} and {@link QuitResponse}
*/
@Deprecated
public void handleQuit(ApplicationEvent event);
/**
* Called when the application receives a Reopen Application event from the Finder or another application. Usually
* this will come when a user clicks on your application icon in the Dock. If there is any special code
* that needs to run when your user clicks on your application icon in the Dock or when a Reopen Application
* event is sent from another application, include that code as part of this handler.
*
* @param event the Reopen Application event
* @deprecated use {@link AppReOpenedListener}
*/
@Deprecated
public void handleReOpenApplication(ApplicationEvent event);
}

View File

@@ -25,7 +25,7 @@
package com.apple.eawt;
import com.apple.eawt.AppEvent.FullScreenEvent;
import com.apple.eawt.event.FullScreenEvent;
/**
* Abstract adapter class for receiving fullscreen events. This class is provided

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,13 @@
package com.apple.eawt;
import com.apple.eawt.event.FullScreenEvent;
import java.awt.*;
import java.util.*;
import java.util.List;
import javax.swing.RootPaneContainer;
import com.apple.eawt.AppEvent.FullScreenEvent;
import sun.awt.SunToolkit;
import java.lang.annotation.Native;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,9 @@
package com.apple.eawt;
import com.apple.eawt.event.FullScreenEvent;
import java.util.EventListener;
import com.apple.eawt.AppEvent.FullScreenEvent;
/**
*
@@ -37,25 +37,25 @@ import com.apple.eawt.AppEvent.FullScreenEvent;
public interface FullScreenListener extends EventListener {
/**
* Invoked when a window has started to enter full screen.
* @param event containing the specific window entering full screen.
* @param e containing the specific window entering full screen.
*/
public void windowEnteringFullScreen(final FullScreenEvent e);
/**
* Invoked when a window has fully entered full screen.
* @param event containing the specific window which has entered full screen.
* @param e containing the specific window which has entered full screen.
*/
public void windowEnteredFullScreen(final FullScreenEvent e);
/**
* Invoked when a window has started to exit full screen.
* @param event containing the specific window exiting full screen.
* @param e containing the specific window exiting full screen.
*/
public void windowExitingFullScreen(final FullScreenEvent e);
/**
* Invoked when a window has fully exited full screen.
* @param event containing the specific window which has exited full screen.
* @param e containing the specific window which has exited full screen.
*/
public void windowExitedFullScreen(final FullScreenEvent e);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,27 +25,25 @@
package com.apple.eawt;
import java.awt.*;
import java.awt.Component;
import java.awt.Window;
import javax.swing.RootPaneContainer;
import sun.lwawt.macosx.*;
import com.apple.eawt.event.GestureUtilities;
import sun.lwawt.macosx.CPlatformWindow;
/**
* Utility class perform animated full screen actions to top-level {@link Window}s.
*
* This class manages the relationship between {@link Windows}s and the {@link FullScreenListener}s
* attached to them. It's design is similar to the Java SE 6u10 {@link com.sun.awt.AWTUtilities}
* class which adds additional functionality to AWT Windows, without adding new API to the
* This class manages the relationship between {@link Window}s and the {@link FullScreenListener}s
* attached to them. It adds additional functionality to AWT Windows, without adding new API to the
* {@link java.awt.Window} class.
*
* Full screen operations can only be performed on top-level {@link Window}s that are also {@link RootPaneContainer}s.
*
* @see FullScreenAdapter
* @see GestureUtilities
* @see com.sun.awt.AWTUtilities
*
* @since Java for Mac OS X 10.7 Update 1
*/

View File

@@ -53,7 +53,7 @@ public class MacQuitResponse implements QuitResponse {
*/
@Override
public void performQuit() {
//if (appEventHandler.currentQuitResponse != this) return;
if (appEventHandler.currentQuitResponse != this) return;
appEventHandler.performQuit();
}
@@ -63,7 +63,7 @@ public class MacQuitResponse implements QuitResponse {
*/
@Override
public void cancelQuit() {
//if (appEventHandler.currentQuitResponse != this) return;
if (appEventHandler.currentQuitResponse != this) return;
appEventHandler.cancelQuit();
}
}

View File

@@ -47,8 +47,6 @@ public class QuitResponse {
* Notifies the external quit requester that the quit will proceed, and performs the default {@link QuitStrategy}.
*/
public void performQuit() {
if (appEventHandler.currentQuitResponse != this) return;
appEventHandler.performQuit();
}
/**
@@ -56,7 +54,5 @@ public class QuitResponse {
* <b>Note: this will cancel a pending log-out, restart, or shutdown.</b>
*/
public void cancelQuit() {
if (appEventHandler.currentQuitResponse != this) return;
appEventHandler.cancelQuit();
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.eawt;
import com.apple.eawt.AppEvent.ScreenSleepEvent;
/**
* Implementors receive notification when the displays attached to the system have entered power save sleep.
*
* This notification is useful for discontinuing a costly animation, or indicating that the user is no longer present on a network service.
*
* This message is not sent on Mac OS X versions prior to 10.6.
*
* @see Application#addAppEventListener(AppEventListener)
*
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
public interface ScreenSleepListener extends AppEventListener {
/**
* Called when the system displays have entered power save sleep.
* @param e the screen sleep event
*/
public void screenAboutToSleep(final ScreenSleepEvent e);
/**
* Called when the system displays have awoke from power save sleep.
* @param e the screen sleep event
*/
public void screenAwoke(final ScreenSleepEvent e);
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.eawt;
import com.apple.eawt.AppEvent.SystemSleepEvent;
/**
* Implementors receive notification as the system is entering sleep, and after the system wakes.
*
* This notification is useful for disconnecting from network services prior to sleep, or re-establishing a connection if the network configuration has changed during sleep.
*
* @see Application#addAppEventListener(AppEventListener)
*
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
public interface SystemSleepListener extends AppEventListener {
/**
* Called when the system is about to sleep.
* Note: This message may not be delivered prior to the actual system sleep, and may be processed after the corresponding wake has occurred.
* @param e the system sleep event
*/
public void systemAboutToSleep(final SystemSleepEvent e);
/**
* Called after the system has awoke from sleeping.
* @param e the system sleep event
*/
public void systemAwoke(final SystemSleepEvent e);
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.eawt;
import com.apple.eawt.AppEvent.UserSessionEvent;
/**
* Implementors receive notification when Fast User Switching changes the user session.
*
* This notification is useful for discontinuing a costly animation, or indicating that the user is no longer present on a network service.
*
* @see Application#addAppEventListener(AppEventListener)
*
* @since Java for Mac OS X 10.6 Update 3
* @since Java for Mac OS X 10.5 Update 8
*/
public interface UserSessionListener extends AppEventListener {
/**
* Called when the user session has been switched away.
* @param e the user session switch event
*/
public void userSessionDeactivated(final UserSessionEvent e);
/**
* Called when the user session has been switched to.
* @param e the user session switch event
*/
public void userSessionActivated(final UserSessionEvent e);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,13 +28,14 @@ package com.apple.eawt;
import java.awt.*;
import java.lang.reflect.*;
import sun.awt.AWTAccessor;
import sun.lwawt.macosx.*;
import sun.lwawt.macosx.CImage.Creator;
import sun.awt.AWTAccessor;
class _AppDockIconHandler {
private static native void nativeSetDockMenu(final long cmenu);
private static native void nativeSetDockIconImage(final long image);
private static native void nativeSetDockIconProgress(final int value);
private static native long nativeGetDockIconImage();
private static native void nativeSetDockIconBadge(final String badge);
@@ -42,7 +43,6 @@ class _AppDockIconHandler {
_AppDockIconHandler() { }
@SuppressWarnings("deprecation")
public void setDockMenu(final PopupMenu menu) {
fDockMenu = menu;
@@ -72,9 +72,8 @@ class _AppDockIconHandler {
public void setDockIconImage(final Image image) {
try {
final CImage cImage = getCImageCreator().createFromImage(image);
final long nsImagePtr = getNSImagePtrFrom(cImage);
nativeSetDockIconImage(nsImagePtr);
final CImage cImage = CImage.createFromImage(image);
cImage.execute(_AppDockIconHandler::nativeSetDockIconImage);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
@@ -84,7 +83,11 @@ class _AppDockIconHandler {
try {
final long dockNSImage = nativeGetDockIconImage();
if (dockNSImage == 0) return null;
return getCImageCreator().createImageUsingNativeSize(dockNSImage);
final Method getCreatorMethod = CImage.class.getDeclaredMethod(
"getCreator", new Class<?>[]{});
getCreatorMethod.setAccessible(true);
Creator imageCreator = (Creator) getCreatorMethod.invoke(null, new Object[]{});
return imageCreator.createImageUsingNativeSize(dockNSImage);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
@@ -94,26 +97,7 @@ class _AppDockIconHandler {
nativeSetDockIconBadge(badge);
}
@SuppressWarnings("rawtypes")
static Creator getCImageCreator() {
try {
final Method getCreatorMethod = CImage.class.getDeclaredMethod("getCreator", new Class[] {});
getCreatorMethod.setAccessible(true);
return (Creator)getCreatorMethod.invoke(null, new Object[] {});
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
static long getNSImagePtrFrom(final CImage cImage) {
if (cImage == null) return 0;
try {
final Field cImagePtrField = CFRetainedResource.class.getDeclaredField("ptr");
cImagePtrField.setAccessible(true);
return cImagePtrField.getLong(cImage);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
void setDockIconProgress(int value) {
nativeSetDockIconProgress(value);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,17 +25,47 @@
package com.apple.eawt;
import java.awt.*;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.desktop.AboutEvent;
import java.awt.desktop.AboutHandler;
import java.awt.desktop.AppForegroundEvent;
import java.awt.desktop.AppForegroundListener;
import java.awt.desktop.AppHiddenEvent;
import java.awt.desktop.AppHiddenListener;
import java.awt.desktop.AppReopenedEvent;
import java.awt.desktop.AppReopenedListener;
import java.awt.desktop.OpenFilesEvent;
import java.awt.desktop.OpenFilesHandler;
import java.awt.desktop.OpenURIEvent;
import java.awt.desktop.OpenURIHandler;
import java.awt.desktop.PreferencesEvent;
import java.awt.desktop.PreferencesHandler;
import java.awt.desktop.PrintFilesEvent;
import java.awt.desktop.PrintFilesHandler;
import java.awt.desktop.QuitEvent;
import java.awt.desktop.QuitHandler;
import java.awt.desktop.QuitStrategy;
import java.awt.desktop.ScreenSleepEvent;
import java.awt.desktop.ScreenSleepListener;
import java.awt.desktop.SystemEventListener;
import java.awt.desktop.SystemSleepEvent;
import java.awt.desktop.SystemSleepListener;
import java.awt.desktop.UserSessionEvent;
import java.awt.desktop.UserSessionEvent.Reason;
import java.awt.desktop.UserSessionListener;
import java.awt.event.WindowEvent;
import java.io.File;
import java.net.*;
import java.util.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
import com.apple.eawt.AppEvent.*;
class _AppEventHandler {
private static final int NOTIFY_ABOUT = 1;
private static final int NOTIFY_PREFS = 2;
@@ -62,7 +92,7 @@ class _AppEventHandler {
private static native void nativeReplyToAppShouldTerminate(final boolean shouldTerminate);
private static native void nativeRegisterForNotification(final int notification);
final static _AppEventHandler instance = new _AppEventHandler();
static final _AppEventHandler instance = new _AppEventHandler();
static _AppEventHandler getInstance() {
return instance;
}
@@ -84,9 +114,7 @@ class _AppEventHandler {
final _ScreenSleepDispatcher screenSleepDispatcher = new _ScreenSleepDispatcher();
final _SystemSleepDispatcher systemSleepDispatcher = new _SystemSleepDispatcher();
final _AppEventLegacyHandler legacyHandler = new _AppEventLegacyHandler(this);
QuitStrategy defaultQuitAction = QuitStrategy.SYSTEM_EXIT_0;
QuitStrategy defaultQuitAction = QuitStrategy.NORMAL_EXIT;
_AppEventHandler() {
final String strategyProp = System.getProperty("apple.eawt.quitStrategy");
@@ -94,15 +122,16 @@ class _AppEventHandler {
if ("CLOSE_ALL_WINDOWS".equals(strategyProp)) {
setDefaultQuitStrategy(QuitStrategy.CLOSE_ALL_WINDOWS);
} else if ("SYSTEM_EXIT_O".equals(strategyProp)) {
setDefaultQuitStrategy(QuitStrategy.SYSTEM_EXIT_0);
} else if ("SYSTEM_EXIT_O".equals(strategyProp)
|| "NORMAL_EXIT".equals(strategyProp)) {
setDefaultQuitStrategy(QuitStrategy.NORMAL_EXIT);
} else {
System.err.println("unrecognized apple.eawt.quitStrategy: " + strategyProp);
}
}
void addListener(final AppEventListener listener) {
if (listener instanceof AppReOpenedListener) reOpenAppDispatcher.addListener((AppReOpenedListener)listener);
void addListener(final SystemEventListener listener) {
if (listener instanceof AppReopenedListener) reOpenAppDispatcher.addListener((AppReopenedListener)listener);
if (listener instanceof AppForegroundListener) foregroundAppDispatcher.addListener((AppForegroundListener)listener);
if (listener instanceof AppHiddenListener) hiddenAppDispatcher.addListener((AppHiddenListener)listener);
if (listener instanceof UserSessionListener) userSessionDispatcher.addListener((UserSessionListener)listener);
@@ -110,8 +139,8 @@ class _AppEventHandler {
if (listener instanceof SystemSleepListener) systemSleepDispatcher.addListener((SystemSleepListener)listener);
}
void removeListener(final AppEventListener listener) {
if (listener instanceof AppReOpenedListener) reOpenAppDispatcher.removeListener((AppReOpenedListener)listener);
void removeListener(final SystemEventListener listener) {
if (listener instanceof AppReopenedListener) reOpenAppDispatcher.removeListener((AppReopenedListener)listener);
if (listener instanceof AppForegroundListener) foregroundAppDispatcher.removeListener((AppForegroundListener)listener);
if (listener instanceof AppHiddenListener) hiddenAppDispatcher.removeListener((AppHiddenListener)listener);
if (listener instanceof UserSessionListener) userSessionDispatcher.removeListener((UserSessionListener)listener);
@@ -127,10 +156,10 @@ class _AppEventHandler {
this.defaultQuitAction = defaultQuitAction;
}
QuitResponse currentQuitResponse;
synchronized QuitResponse obtainQuitResponse() {
MacQuitResponse currentQuitResponse;
synchronized MacQuitResponse obtainQuitResponse() {
if (currentQuitResponse != null) return currentQuitResponse;
return currentQuitResponse = new QuitResponse(this);
return currentQuitResponse = new MacQuitResponse(this);
}
synchronized void cancelQuit() {
@@ -142,7 +171,8 @@ class _AppEventHandler {
currentQuitResponse = null;
try {
if (defaultQuitAction == QuitStrategy.SYSTEM_EXIT_0) System.exit(0);
if (defaultQuitAction == QuitStrategy.NORMAL_EXIT
|| _AppMiscHandlers.isSuddenTerminationEnbaled()) System.exit(0);
if (defaultQuitAction != QuitStrategy.CLOSE_ALL_WINDOWS) {
throw new RuntimeException("Unknown quit action");
@@ -270,10 +300,10 @@ class _AppEventHandler {
}
}
class _AppReOpenedDispatcher extends _AppEventMultiplexor<AppReOpenedListener> {
void performOnListener(AppReOpenedListener listener, final _NativeEvent event) {
final AppReOpenedEvent e = new AppReOpenedEvent();
listener.appReOpened(e);
class _AppReOpenedDispatcher extends _AppEventMultiplexor<AppReopenedListener> {
void performOnListener(AppReopenedListener listener, final _NativeEvent event) {
final AppReopenedEvent e = new AppReopenedEvent();
listener.appReopened(e);
}
}
@@ -302,7 +332,9 @@ class _AppEventHandler {
}
class _UserSessionDispatcher extends _BooleanAppEventMultiplexor<UserSessionListener, UserSessionEvent> {
UserSessionEvent createEvent(final boolean isTrue) { return new UserSessionEvent(); }
UserSessionEvent createEvent(final boolean isTrue) {
return new UserSessionEvent(Reason.UNSPECIFIED);
}
void performFalseEventOn(final UserSessionListener listener, final UserSessionEvent e) {
listener.userSessionDeactivated(e);
@@ -391,7 +423,11 @@ class _AppEventHandler {
}
void performUsing(final QuitHandler handler, final _NativeEvent event) {
final QuitResponse response = obtainQuitResponse(); // obtains the "current" quit response
if (_AppMiscHandlers.isSuddenTerminationEnbaled()) {
performDefaultAction(event);
return;
}
final MacQuitResponse response = obtainQuitResponse(); // obtains the "current" quit response
handler.handleQuitRequestWith(new QuitEvent(), response);
}
}
@@ -524,9 +560,6 @@ class _AppEventHandler {
setHandlerContext(AppContext.getAppContext());
// if a new handler is installed, block addition of legacy ApplicationListeners
if (handler == legacyHandler) return;
legacyHandler.blockLegacyAPI();
}
void performDefaultAction(final _NativeEvent event) { } // by default, do nothing
@@ -574,10 +607,6 @@ class _AppEventHandler {
}
}
}
// if a new handler is installed, block addition of legacy ApplicationListeners
if (handler == legacyHandler) return;
legacyHandler.blockLegacyAPI();
}
}
}

View File

@@ -1,188 +0,0 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.eawt;
import java.awt.Toolkit;
import java.io.File;
import java.util.*;
import com.apple.eawt.AppEvent.*;
@SuppressWarnings("deprecation")
class _AppEventLegacyHandler implements AboutHandler, PreferencesHandler, _OpenAppHandler, AppReOpenedListener, OpenFilesHandler, PrintFilesHandler, QuitHandler {
final _AppEventHandler parent;
final Vector<ApplicationListener> legacyAppListeners = new Vector<ApplicationListener>();
boolean blockLegacyAPI;
boolean initializedParentDispatchers;
_AppEventLegacyHandler(final _AppEventHandler parent) {
this.parent = parent;
}
void blockLegacyAPI() {
blockLegacyAPI = true;
}
void checkIfLegacyAPIBlocked() {
if (!blockLegacyAPI) return;
throw new IllegalStateException("Cannot add com.apple.eawt.ApplicationListener after installing an app event handler");
}
void addLegacyAppListener(final ApplicationListener listener) {
checkIfLegacyAPIBlocked();
if (!initializedParentDispatchers) {
final _AppMenuBarHandler menuBarHandler = Application.getApplication().menuBarHandler;
final boolean prefsMenuAlreadyExplicitlySet = menuBarHandler.prefsMenuItemExplicitlySet;
parent.aboutDispatcher.setHandler(this);
parent.preferencesDispatcher.setHandler(this);
if (!prefsMenuAlreadyExplicitlySet) {
menuBarHandler.setPreferencesMenuItemVisible(false); // default behavior is not to have a preferences item
}
parent.openAppDispatcher.setHandler(this);
parent.reOpenAppDispatcher.addListener(this);
parent.openFilesDispatcher.setHandler(this);
parent.printFilesDispatcher.setHandler(this);
parent.quitDispatcher.setHandler(this);
initializedParentDispatchers = true;
}
synchronized (legacyAppListeners) {
legacyAppListeners.addElement(listener);
}
}
public void removeLegacyAppListener(final ApplicationListener listener) {
checkIfLegacyAPIBlocked();
synchronized (legacyAppListeners) {
legacyAppListeners.removeElement(listener);
}
}
@Override
public void handleAbout(final AboutEvent e) {
final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit());
sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
public void dispatchEvent(final ApplicationListener listener) {
listener.handleAbout(ae);
}
});
if (ae.isHandled()) return;
parent.openCocoaAboutWindow();
}
@Override
public void handlePreferences(final PreferencesEvent e) {
final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit());
sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
public void dispatchEvent(final ApplicationListener listener) {
listener.handlePreferences(ae);
}
});
}
@Override
public void handleOpenApp() {
final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit());
sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
public void dispatchEvent(final ApplicationListener listener) {
listener.handleOpenApplication(ae);
}
});
}
@Override
public void appReOpened(final AppReOpenedEvent e) {
final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit());
sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
public void dispatchEvent(final ApplicationListener listener) {
listener.handleReOpenApplication(ae);
}
});
}
@Override
public void openFiles(final OpenFilesEvent e) {
final List<File> files = e.getFiles();
for (final File file : files) { // legacy ApplicationListeners only understood one file at a time
final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit(), file.getAbsolutePath());
sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
public void dispatchEvent(final ApplicationListener listener) {
listener.handleOpenFile(ae);
}
});
}
}
@Override
public void printFiles(PrintFilesEvent e) {
final List<File> files = e.getFiles();
for (final File file : files) { // legacy ApplicationListeners only understood one file at a time
final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit(), file.getAbsolutePath());
sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
public void dispatchEvent(final ApplicationListener listener) {
listener.handlePrintFile(ae);
}
});
}
}
@Override
public void handleQuitRequestWith(final QuitEvent e, final QuitResponse response) {
final ApplicationEvent ae = new ApplicationEvent(Toolkit.getDefaultToolkit());
sendEventToEachListenerUntilHandled(ae, new EventDispatcher() {
public void dispatchEvent(final ApplicationListener listener) {
listener.handleQuit(ae);
}
});
if (ae.isHandled()) {
parent.performQuit();
} else {
parent.cancelQuit();
}
}
interface EventDispatcher {
void dispatchEvent(final ApplicationListener listener);
}
// helper that cycles through the loop and aborts if the event is handled, or there are no listeners
void sendEventToEachListenerUntilHandled(final ApplicationEvent event, final EventDispatcher dispatcher) {
synchronized (legacyAppListeners) {
if (legacyAppListeners.size() == 0) return;
final Enumeration<ApplicationListener> e = legacyAppListeners.elements();
while (e.hasMoreElements() && !event.isHandled()) {
dispatcher.dispatchEvent(e.nextElement());
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,17 +25,20 @@
package com.apple.eawt;
import java.awt.Container;
import java.awt.Frame;
import java.awt.peer.MenuComponentPeer;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JMenuBar;
import javax.swing.plaf.MenuBarUI;
import com.apple.laf.ScreenMenuBar;
import sun.awt.AWTAccessor;
import sun.lwawt.macosx.CMenuBar;
import com.apple.laf.AquaMenuBarUI;
import sun.awt.AWTAccessor;
class _AppMenuBarHandler {
private static final int MENU_ABOUT = 1;
@@ -43,14 +46,20 @@ class _AppMenuBarHandler {
private static native void nativeSetMenuState(final int menu, final boolean visible, final boolean enabled);
private static native void nativeSetDefaultMenuBar(final long menuBarPeer);
private static native void nativeActivateDefaultMenuBar(final long menuBarPeer);
static final _AppMenuBarHandler instance = new _AppMenuBarHandler();
static _AppMenuBarHandler getInstance() {
return instance;
}
private static ScreenMenuBar defaultMenuBar;
// callback from the native delegate -init function
private static void initMenuStates(final boolean aboutMenuItemVisible, final boolean aboutMenuItemEnabled, final boolean prefsMenuItemVisible, final boolean prefsMenuItemEnabled) {
private static void initMenuStates(final boolean aboutMenuItemVisible,
final boolean aboutMenuItemEnabled,
final boolean prefsMenuItemVisible,
final boolean prefsMenuItemEnabled) {
synchronized (instance) {
instance.aboutMenuItemVisible = aboutMenuItemVisible;
instance.aboutMenuItemEnabled = aboutMenuItemEnabled;
@@ -70,41 +79,45 @@ class _AppMenuBarHandler {
void setDefaultMenuBar(final JMenuBar menuBar) {
installDefaultMenuBar(menuBar);
}
static boolean isMenuBarActivationNeeded() {
// scan the current frames, and see if any are foreground
final Frame[] frames = Frame.getFrames();
for (final Frame frame : frames) {
if (frame.isVisible() && !isFrameMinimized(frame)) {
return;
return false;
}
}
// if we have no foreground frames, then we have to "kick" the menubar
final JFrame pingFrame = new JFrame();
pingFrame.getRootPane().putClientProperty("Window.alpha", Float.valueOf(0.0f));
pingFrame.setUndecorated(true);
pingFrame.setVisible(true);
pingFrame.toFront();
pingFrame.setVisible(false);
pingFrame.dispose();
return true;
}
static boolean isFrameMinimized(final Frame frame) {
return (frame.getExtendedState() & Frame.ICONIFIED) != 0;
}
@SuppressWarnings("deprecation")
static void installDefaultMenuBar(final JMenuBar menuBar) {
if (menuBar == null) {
// intentionally clearing the default menu
if (defaultMenuBar != null) {
defaultMenuBar.removeNotify();
defaultMenuBar = null;
}
nativeSetDefaultMenuBar(0);
return;
}
final MenuBarUI ui = menuBar.getUI();
Container parent = menuBar.getParent();
if (parent instanceof JLayeredPane) {
((JLayeredPane) parent).remove(menuBar);
}
MenuBarUI ui = menuBar.getUI();
if (!(ui instanceof AquaMenuBarUI)) {
// Aqua was not installed
throw new IllegalStateException("Application.setDefaultMenuBar() only works with the Aqua Look and Feel");
ui = new AquaMenuBarUI();
menuBar.setUI(ui);
}
final AquaMenuBarUI aquaUI = (AquaMenuBarUI)ui;
@@ -114,7 +127,14 @@ class _AppMenuBarHandler {
throw new IllegalStateException("Application.setDefaultMenuBar() only works if apple.laf.useScreenMenuBar=true");
}
screenMenuBar.addNotify();
if (screenMenuBar != defaultMenuBar) {
if (defaultMenuBar != null) {
defaultMenuBar.removeNotify();
}
defaultMenuBar = screenMenuBar;
screenMenuBar.addNotify();
}
final Object peer = AWTAccessor.getMenuComponentAccessor().getPeer(screenMenuBar);
if (!(peer instanceof CMenuBar)) {
// such a thing should not be possible
@@ -123,6 +143,11 @@ class _AppMenuBarHandler {
// grab the pointer to the CMenuBar, and retain it in native
((CMenuBar) peer).execute(_AppMenuBarHandler::nativeSetDefaultMenuBar);
// if there is no currently active frame, install the default menu bar in the application main menu
if (isMenuBarActivationNeeded()) {
((CMenuBar) peer).execute(_AppMenuBarHandler::nativeActivateDefaultMenuBar);
}
}
void setAboutMenuItemVisible(final boolean present) {

View File

@@ -26,6 +26,8 @@
package com.apple.eawt;
class _AppMiscHandlers {
private static boolean isSuddenTerminationEnabled;
private static native void nativeOpenHelpViewer();
private static native void nativeRequestActivation(final boolean allWindows);
@@ -47,10 +49,16 @@ class _AppMiscHandlers {
}
static void enableSuddenTermination() {
isSuddenTerminationEnabled = true;
nativeEnableSuddenTermination();
}
static void disableSuddenTermination() {
isSuddenTerminationEnabled = false;
nativeDisableSuddenTermination();
}
public static boolean isSuddenTerminationEnbaled() {
return isSuddenTerminationEnabled;
}
}

View File

@@ -27,4 +27,4 @@ package com.apple.eawt;
interface _OpenAppHandler {
void handleOpenApp();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@ package com.apple.eawt.event;
* Abstract adapter class for receiving gesture events. This class is provided
* as a convenience for creating listeners.
*
* Subclasses registered with {@link GestureUtilities#addGestureListenerTo()}
* Subclasses registered with {@link GestureUtilities#addGestureListenerTo}
* will receive all phase, magnification, rotation, and swipe events.
*
* @see GestureUtilities

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
package com.apple.eawt.event;
import java.awt.*;
import java.awt.event.InputEvent;
/**
* Abstract event all gestures inherit from.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,13 +39,13 @@ package com.apple.eawt.event;
public interface GesturePhaseListener extends GestureListener {
/**
* Invoked when the user has started a continuous gesture.
* @param event representing the start of a continuous gesture.
* @param e representing the start of a continuous gesture.
*/
public void gestureBegan(final GesturePhaseEvent e);
/**
* Invoked when the user has stopped a continuous gesture.
* @param event representing the end of a continuous gesture.
* @param e representing the end of a continuous gesture.
*/
public void gestureEnded(final GesturePhaseEvent e);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,15 @@
package com.apple.eawt.event;
import javax.swing.*;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JRootPane;
/**
* Registration utility class to add {@link GestureListener}s to Swing components.
*
* This class manages the relationship between {@link JComponent}s and the {@link GestureListener}s
* attached to them. It's design is similar to the Java SE 6u10 {@link com.sun.awt.AWTUtilities}
* class which adds additional functionality to AWT Windows, without adding new API to the
* attached to them. It adds additional functionality to AWT Windows, without adding new API to the
* {@link java.awt.Window} class.
*
* To add a {@link GestureListener} to a top-level Swing window, use the {@link JRootPane} of the
@@ -40,7 +41,6 @@ import javax.swing.*;
*
* @see GestureAdapter
* @see JFrame#getRootPane()
* @see com.sun.awt.AWTUtilities
*
* @since Java for Mac OS X 10.5 Update 7, Java for Mac OS X 10.6 Update 2
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@ package com.apple.eawt.event;
public interface MagnificationListener extends GestureListener {
/**
* Invoked when a magnification gesture is performed by the user.
* @param event containing the scale of the magnification.
* @param e containing the scale of the magnification.
*/
public void magnify(final MagnificationEvent e);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@ package com.apple.eawt.event;
public interface RotationListener extends GestureListener {
/**
* Invoked when a rotation gesture is performed by the user.
* @param event containing an abstract measure of rotation.
* @param e containing an abstract measure of rotation.
*/
public void rotate(final RotationEvent e);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,25 +38,25 @@ package com.apple.eawt.event;
public interface SwipeListener extends GestureListener {
/**
* Invoked when an upwards swipe gesture is performed by the user.
* @param event representing the occurrence of a swipe.
* @param e representing the occurrence of a swipe.
*/
public void swipedUp(final SwipeEvent e);
/**
* Invoked when a downward swipe gesture is performed by the user.
* @param event representing the occurrence of a swipe.
* @param e representing the occurrence of a swipe.
*/
public void swipedDown(final SwipeEvent e);
/**
* Invoked when a leftward swipe gesture is performed by the user.
* @param event representing the occurrence of a swipe.
* @param e representing the occurrence of a swipe.
*/
public void swipedLeft(final SwipeEvent e);
/**
* Invoked when a rightward swipe gesture is performed by the user.
* @param event representing the occurrence of a swipe.
* @param e representing the occurrence of a swipe.
*/
public void swipedRight(final SwipeEvent e);
}

View File

@@ -1,13 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body bgcolor="white">
Classes for receiving gesture events.
Provides a mechanism to receive various gesture events on JComponents. Gesture notifications are relayed up the component hierarchy from the deepest component under the cursor to the top-level container. Events may be consumed by deeper components to prevent them from propagating to higher components.
Gesture listeners are added to components using the GestureUtilities helper class.
</body>
</html>

View File

@@ -1,10 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
</head>
<body bgcolor="white">
Provides classes for integrating Java applications with the native application environment.
These classes provide a simple way to implement native features to fine tune Java applications on Mac OS X. These listeners and handlers can help make Java applications behaviors and user interface indistinguishable from native applications. For further information on the Mac OS X user interface, consult the <a target=_blank href="http://developer.apple.com/mac/library/documentation/UserExperience/Conceptual/AppleHIGuidelines"> Aqua Human Interface Guidelines</a>.</body>
</html>

View File

@@ -100,6 +100,17 @@ final class ScreenMenuItem extends MenuItem
fMenuItem.removeComponentListener(this);
}
static void syncAcceleratorText(MenuItem menuItem, JMenuItem fMenuItem) {
Object acceleratorText = fMenuItem.getClientProperty("accelerator.text");
if (acceleratorText instanceof String) {
Object peer = AWTAccessor.getMenuComponentAccessor().getPeer(menuItem);
if (peer instanceof CMenuItem) {
final CMenuItem cmi = (CMenuItem) peer;
cmi.setAcceleratorText((String)acceleratorText);
}
}
}
static void syncLabelAndKS(MenuItem menuItem, String label, KeyStroke ks) {
Object peer = AWTAccessor.getMenuComponentAccessor().getPeer(menuItem);
if (!(peer instanceof CMenuItem)) {
@@ -123,6 +134,12 @@ final class ScreenMenuItem extends MenuItem
@Override
public void setAccelerator(final KeyStroke ks) {
syncLabelAndKS(this, fMenuItem.getText(), ks);
syncAcceleratorText(this, fMenuItem);
}
@Override
public void setAcceleratorText(String acceleratorText) {
syncAcceleratorText(this, fMenuItem);
}
public void actionPerformed(final ActionEvent e) {

View File

@@ -123,6 +123,12 @@ final class ScreenMenuItemCheckbox extends CheckboxMenuItem
@Override
public void setAccelerator(final KeyStroke ks) {
ScreenMenuItem.syncLabelAndKS(this, fMenuItem.getText(), ks);
ScreenMenuItem.syncAcceleratorText(this, fMenuItem);
}
@Override
public void setAcceleratorText(String acceleratorText) {
ScreenMenuItem.syncAcceleratorText(this, fMenuItem);
}
public void actionPerformed(final ActionEvent e) {

View File

@@ -36,6 +36,7 @@ interface ScreenMenuPropertyHandler {
public void setLabel(String f);
public void setIcon(Icon icon);
public void setAccelerator(KeyStroke ks);
default void setAcceleratorText(String acceleratorText) {}
public void setToolTipText(String tooltip);
public void setChildVisible(javax.swing.JMenuItem child, boolean b);
public void setIndeterminate(boolean indeterminate);

View File

@@ -67,6 +67,11 @@ class ScreenMenuPropertyListener implements PropertyChangeListener {
return;
}
if ("accelerator.text".equals(propertyName)) {
fMenu.setAcceleratorText((String)e.getNewValue());
return;
}
if (AbstractButton.TEXT_CHANGED_PROPERTY.equals(propertyName)) {
fMenu.setLabel((String)e.getNewValue());
return;

View File

@@ -40,7 +40,9 @@ public final class CStrike extends PhysicalStrike {
double[] glyphTx,
double[] invDevTxMatrix,
int aaHint,
int fmHint);
int fmHint,
int subpixelResolutionX,
int subpixelResolutionY);
// Disposes the native strike
private static native void disposeNativeStrikePtr(long nativeStrikePtr);
@@ -127,7 +129,9 @@ public final class CStrike extends PhysicalStrike {
}
nativeStrikePtr =
createNativeStrikePtr(nativeFont.getNativeFontPtr(),
glyphTx, invDevTxMatrix, aaHint, fmHint);
glyphTx, invDevTxMatrix, aaHint, fmHint,
FontUtilities.supplementarySubpixelGlyphResolution.width,
FontUtilities.supplementarySubpixelGlyphResolution.height);
}
return nativeStrikePtr;

View File

@@ -234,6 +234,7 @@ public class LWWindowPeer
setOpaque(getTarget().isOpaque());
updateInsets(platformWindow.getInsets());
if (getSurfaceData() == null) {
replaceSurfaceData(false);
}
@@ -310,7 +311,6 @@ public class LWWindowPeer
}
}
}
updateInsets(platformWindow.getInsets());
}
@Override

View File

@@ -76,72 +76,72 @@ final public class CDesktopPeer implements DesktopPeer {
@Override
public void addAppEventListener(SystemEventListener listener) {
//Application.getApplication().addAppEventListener(listener);
Application.getApplication().addAppEventListener(listener);
}
@Override
public void removeAppEventListener(SystemEventListener listener) {
//Application.getApplication().removeAppEventListener(listener);
Application.getApplication().removeAppEventListener(listener);
}
@Override
public void setAboutHandler(AboutHandler aboutHandler) {
// Application.getApplication().setAboutHandler(aboutHandler);
Application.getApplication().setAboutHandler(aboutHandler);
}
@Override
public void setPreferencesHandler(PreferencesHandler preferencesHandler) {
// Application.getApplication().setPreferencesHandler(preferencesHandler);
Application.getApplication().setPreferencesHandler(preferencesHandler);
}
@Override
public void setOpenFileHandler(OpenFilesHandler openFileHandler) {
// Application.getApplication().setOpenFileHandler(openFileHandler);
Application.getApplication().setOpenFileHandler(openFileHandler);
}
@Override
public void setPrintFileHandler(PrintFilesHandler printFileHandler) {
// Application.getApplication().setPrintFileHandler(printFileHandler);
Application.getApplication().setPrintFileHandler(printFileHandler);
}
@Override
public void setOpenURIHandler(OpenURIHandler openURIHandler) {
// Application.getApplication().setOpenURIHandler(openURIHandler);
Application.getApplication().setOpenURIHandler(openURIHandler);
}
@Override
public void setQuitHandler(QuitHandler quitHandler) {
// Application.getApplication().setQuitHandler(quitHandler);
Application.getApplication().setQuitHandler(quitHandler);
}
@Override
public void setQuitStrategy(QuitStrategy strategy) {
// Application.getApplication().setQuitStrategy(strategy);
Application.getApplication().setQuitStrategy(strategy);
}
@Override
public void enableSuddenTermination() {
// Application.getApplication().enableSuddenTermination();
Application.getApplication().enableSuddenTermination();
}
@Override
public void disableSuddenTermination() {
// Application.getApplication().disableSuddenTermination();
Application.getApplication().disableSuddenTermination();
}
@Override
public void requestForeground(boolean allWindows) {
// Application.getApplication().requestForeground(allWindows);
Application.getApplication().requestForeground(allWindows);
}
@Override
public void openHelpViewer() {
// Application.getApplication().openHelpViewer();
Application.getApplication().openHelpViewer();
}
@Override
public void setDefaultMenuBar(JMenuBar menuBar) {
// Application.getApplication().setDefaultMenuBar(menuBar);
Application.getApplication().setDefaultMenuBar(menuBar);
}
@Override

View File

@@ -100,8 +100,12 @@ public class CEmbeddedFrame extends EmbeddedFrame {
deltaY, NSEvent.SCROLL_PHASE_UNSUPPORTED);
}
public void handleKeyEvent(NSEvent nsEvent) {
responder.handleKeyEvent(nsEvent);
public void handleKeyEvent(int eventType, int modifierFlags, String characters,
String charsIgnoringMods, boolean isRepeat, short keyCode,
boolean needsKeyTyped) {
responder.handleKeyEvent(eventType, modifierFlags, characters,
charsIgnoringMods, /*charsIgnoringModifiersAndShift*/ null,
keyCode, needsKeyTyped, isRepeat);
}
public void handleInputEvent(String text) {

View File

@@ -104,6 +104,10 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer {
setLabel(label, (char)0, KeyEvent.VK_UNDEFINED, 0);
}
public void setAcceleratorText(String acceleratorText) {
execute(ptr -> nativeSetAcceleratorText(ptr, acceleratorText));
}
/**
* This is new API that we've added to AWT menu items
* because AWT menu items are used for Swing screen menu bars
@@ -150,6 +154,7 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer {
private native void nativeSetImage(long modelPtr, long image);
private native void nativeSetTooltip(long modelPtr, String text);
private native void nativeSetEnabled(long modelPtr, boolean b);
private native void nativeSetAcceleratorText(long modelPtr, String acceleratorText);
// native callbacks
void handleAction(final long when, final int modifiers) {

View File

@@ -29,24 +29,20 @@ import sun.awt.SunToolkit;
import sun.awt.event.KeyEventProcessing;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.PlatformEventNotifier;
import sun.util.logging.PlatformLogger;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.InputEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.KeyEvent;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Locale;import java.util.MissingResourceException;import java.util.ResourceBundle;
import java.util.Locale;
/**
* Translates NSEvents/NPCocoaEvents into AWT events.
*/
final class CPlatformResponder {
private static final PlatformLogger keyboardLog = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformResponder");
private final PlatformEventNotifier eventNotifier;
private final boolean isNpapiCallback;
private int lastKeyPressCode = KeyEvent.VK_UNDEFINED;
@@ -61,7 +57,6 @@ final class CPlatformResponder {
private int lastDraggedRelativeX;
private int lastDraggedRelativeY;
CPlatformResponder(final PlatformEventNotifier eventNotifier,
final boolean isNpapiCallback) {
this.eventNotifier = eventNotifier;
@@ -166,41 +161,6 @@ final class CPlatformResponder {
-roundDelta, -delta, null);
}
private void handleFlagChangedEvent(int modifierFlags, short keyCode) {
int[] in = new int[] {modifierFlags, keyCode};
int[] out = new int[3]; // [jkeyCode, jkeyLocation, jkeyType]
NSEvent.nsKeyModifiersToJavaKeyInfo(in, out);
int jkeyCode = out[0];
int jkeyLocation = out[1];
int jeventType = out[2];
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
long when = System.currentTimeMillis();
if (jeventType == KeyEvent.KEY_PRESSED) {
lastKeyPressCode = jkeyCode;
}
eventNotifier.notifyKeyEvent(jeventType, when, jmodifiers,
jkeyCode, KeyEvent.CHAR_UNDEFINED, jkeyLocation);
}
private static char mapNsCharsToCompatibleWithJava (char ch) {
switch (ch) {
case 0x0003: // NSEnterCharacter
case 0x000d: // NSCarriageReturnCharacter
return 0x000a; // NSNewlineCharacter
// case 0x007f: // NSDeleteCharacter
// return 0x0008; // NSBackspaceCharacter
case 0xF728: // NSDeleteFunctionKey
return 0x0008; // NSDeleteCharacter
case 0x0019: // NSBackTabCharacter
return 0x0009; // NSTabCharacter
}
return ch;
}
private static final String [] cyrillicKeyboardLayouts = new String [] {
"com.apple.keylayout.Russian",
"com.apple.keylayout.RussianWin",
@@ -216,181 +176,6 @@ final class CPlatformResponder {
return Arrays.stream(cyrillicKeyboardLayouts).anyMatch(l -> l.equals(LWCToolkit.getKeyboardLayoutId()));
}
/**
* Handles key events.
*/
void handleKeyEvent(NSEvent nsEvent)
{
if (!KeyEventProcessing.useNationalLayouts || isCyrillicKeyboardLayout()) {
handleKeyEvent(
nsEvent.getType(),
nsEvent.getModifierFlags(),
nsEvent.getOldCharacters(),
nsEvent.getOldCharactersIgnoringModifiers(),
nsEvent.getKeyCode(),
true,
false
);
return;
}
boolean isFlagsChangedEvent =
isNpapiCallback ? (nsEvent.getType() == CocoaConstants.NPCocoaEventFlagsChanged) :
(nsEvent.getType() == CocoaConstants.NSFlagsChanged);
int jeventType = KeyEvent.KEY_PRESSED;
int jkeyCode = KeyEvent.VK_UNDEFINED;
int jkeyLocation = KeyEvent.KEY_LOCATION_UNKNOWN;
boolean postsTyped = false;
boolean spaceKeyTyped = false;
if (isFlagsChangedEvent) {
handleFlagChangedEvent(nsEvent.getModifierFlags(), nsEvent.getKeyCode());
return;
}
int jmodifiers = NSEvent.nsToJavaModifiers(nsEvent.getModifierFlags());
boolean metaAltCtrlAreNotPressed = (jmodifiers &
(InputEvent.META_DOWN_MASK
| InputEvent.ALT_DOWN_MASK
| InputEvent.CTRL_DOWN_MASK)
) == 0;
boolean shiftIsPressed = (jmodifiers & InputEvent.SHIFT_DOWN_MASK) != 0;
boolean useShiftedCharacters = metaAltCtrlAreNotPressed && shiftIsPressed;
boolean shiftAltDownAreNotPressed = (jmodifiers &
(InputEvent.META_DOWN_MASK
| InputEvent.ALT_DOWN_MASK
| InputEvent.SHIFT_DOWN_MASK)
) == 0;
boolean ctrlIsPressed = (jmodifiers & InputEvent.CTRL_DOWN_MASK) != 0;
boolean isISOControl = false;
char checkedChar = (nsEvent.getCharacters() == null
|| nsEvent.getCharacters().isEmpty()) ? KeyEvent.CHAR_UNDEFINED : nsEvent.getCharacters().charAt(0);
if (shiftAltDownAreNotPressed && ctrlIsPressed) {
if (Character.isISOControl(checkedChar)) {
isISOControl = true;
}
}
char characterToGetKeyCode = KeyEvent.CHAR_UNDEFINED;
boolean charactersIgnoringModifiersIsValid = (nsEvent.getCharactersIgnoringModifiers() != null && nsEvent.getCharactersIgnoringModifiers().length() > 0);
boolean charactersIsValid = (nsEvent.getCharacters() != null && nsEvent.getCharacters().length() > 0);
// We use this char to find a character that is printed depending on pressing modifiers
characterToGetKeyCode = charactersIgnoringModifiersIsValid
? nsEvent.getCharactersIgnoringModifiers().charAt(0)
: charactersIsValid ? nsEvent.getCharacters().charAt(0) : KeyEvent.CHAR_UNDEFINED;
if (useShiftedCharacters && nsEvent.getCharactersIgnoringModifiers() != null && !nsEvent.getCharactersIgnoringModifiers().isEmpty()) {
characterToGetKeyCode = nsEvent.getCharactersIgnoringModifiers().charAt(0);
} else if (nsEvent.getCharactersIgnoringModifiersAndShift() != null && !nsEvent.getCharactersIgnoringModifiersAndShift().isEmpty()) {
characterToGetKeyCode = nsEvent.getCharactersIgnoringModifiersAndShift().charAt(0);
} else if (nsEvent.getCharacters() != null && !nsEvent.getCharacters().isEmpty() && metaAltCtrlAreNotPressed && shiftIsPressed) {
characterToGetKeyCode = checkedChar;
}
// We use char candidate if modifiers are not used
// otherwise, we use char ignoring modifiers
int[] in = new int[] {
characterToGetKeyCode,
nsEvent.isHasDeadKey() ? 1 : 0,
nsEvent.getModifierFlags(),
nsEvent.getKeyCode(),
/*useNationalLayouts*/ 1
};
int[] out = new int[3]; // [jkeyCode, jkeyLocation, deadChar]
postsTyped = NSEvent.nsToJavaKeyInfo(in, out);
char characterToSendWithTheEvent = characterToGetKeyCode;
if(nsEvent.isHasDeadKey()){
characterToSendWithTheEvent = (char) out[2];
jkeyCode = nsEvent.getDeadKeyCode();
if(characterToSendWithTheEvent == 0){
return;
}
}
// If Pinyin Simplified input method is selected, CAPS_LOCK key is supposed to switch
// input to la tin letters.
// It is necessary to use charIgnoringModifiers instead of charCandidate for event
// generation in such case to avoid uppercase letters in text components.
LWCToolkit lwcToolkit = (LWCToolkit)Toolkit.getDefaultToolkit();
if (lwcToolkit.getLockingKeyState(KeyEvent.VK_CAPS_LOCK) &&
Locale.SIMPLIFIED_CHINESE.equals(lwcToolkit.getDefaultKeyboardLocale())) {
characterToSendWithTheEvent = characterToGetKeyCode;
}
jkeyCode = out[0];
jkeyLocation = out[1];
jeventType = isNpapiCallback ? NSEvent.npToJavaEventType(nsEvent.getType()) :
NSEvent.nsToJavaEventType(nsEvent.getType());
if (isISOControl) {
characterToSendWithTheEvent = checkedChar;
} else {
characterToSendWithTheEvent = mapNsCharsToCompatibleWithJava(characterToSendWithTheEvent);
}
String stringWithChar = NSEvent.nsToJavaChar(characterToSendWithTheEvent, nsEvent.getModifierFlags(), spaceKeyTyped);
characterToSendWithTheEvent = stringWithChar == null ? KeyEvent.CHAR_UNDEFINED : stringWithChar.charAt(0);
long when = System.currentTimeMillis();
if (jeventType == KeyEvent.KEY_PRESSED) {
lastKeyPressCode = jkeyCode;
}
eventNotifier.notifyKeyEvent(jeventType, when, jmodifiers,
jkeyCode, characterToSendWithTheEvent, jkeyLocation);
// Current browser may be sending input events, so don't
// post the KEY_TYPED here.
postsTyped &= true;
// That's the reaction on the PRESSED (not RELEASED) event as it comes to
// appear in MacOSX.
// Modifier keys (shift, etc) don't want to send TYPED events.
// On the other hand we don't want to generate keyTyped events
// for clipboard related shortcuts like Meta + [CVX]
if (jeventType == KeyEvent.KEY_PRESSED && postsTyped &&
(jmodifiers & KeyEvent.META_DOWN_MASK) == 0) {
char characterToSendWithTypedEvent = KeyEvent.CHAR_UNDEFINED;
if (nsEvent.getCharacters()!= null ) {
characterToSendWithTypedEvent = mapNsCharsToCompatibleWithJava(checkedChar);
stringWithChar = NSEvent.nsToJavaChar(characterToSendWithTypedEvent, nsEvent.getModifierFlags(), spaceKeyTyped);
characterToSendWithTypedEvent = stringWithChar == null ? KeyEvent.CHAR_UNDEFINED : stringWithChar.charAt(0);
}
boolean nonInputMethodsModifiersAreNotPressed = (jmodifiers &
(InputEvent.META_DOWN_MASK | InputEvent.CTRL_DOWN_MASK)
) == 0;
if (nonInputMethodsModifiersAreNotPressed) {
eventNotifier.notifyKeyEvent(KeyEvent.KEY_TYPED, when, jmodifiers,
jkeyCode, characterToSendWithTypedEvent,
KeyEvent.KEY_LOCATION_UNKNOWN);
}
}
}
void handleInputEvent(String text) {
if (text != null) {
int index = 0, length = text.length();
@@ -412,10 +197,9 @@ final class CPlatformResponder {
/**
* Handles key events.
* @deprecated
*/
@Deprecated
void handleKeyEvent(int eventType, int modifierFlags, String chars, String charsIgnoringModifiers,
void handleKeyEvent(int eventType, int modifierFlags, String chars,
String charsIgnoringModifiers, String charsIgnoringModifiersAndShift,
short keyCode, boolean needsKeyTyped, boolean needsKeyReleased) {
boolean isFlagsChangedEvent =
isNpapiCallback ? (eventType == CocoaConstants.NPCocoaEventFlagsChanged) :
@@ -425,6 +209,9 @@ final class CPlatformResponder {
int jkeyCode = KeyEvent.VK_UNDEFINED;
int jkeyLocation = KeyEvent.KEY_LOCATION_UNKNOWN;
boolean postsTyped = false;
boolean spaceKeyTyped = false;
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
char testChar = KeyEvent.CHAR_UNDEFINED;
boolean isDeadChar = (chars!= null && chars.length() == 0);
@@ -441,12 +228,26 @@ final class CPlatformResponder {
} else {
if (chars != null && chars.length() > 0) {
testChar = chars.charAt(0);
//Check if String chars contains SPACE character.
if (chars.trim().isEmpty()) {
spaceKeyTyped = true;
}
}
// Workaround for JBR-2981
int metaAltCtrlMods = KeyEvent.META_DOWN_MASK | KeyEvent.ALT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK;
boolean metaAltCtrlAreNotPressed = (jmodifiers & metaAltCtrlMods) == 0;
boolean useShiftedCharacter = ((jmodifiers & KeyEvent.SHIFT_DOWN_MASK) == KeyEvent.SHIFT_DOWN_MASK) && metaAltCtrlAreNotPressed;
char testCharIgnoringModifiers = charsIgnoringModifiers != null && charsIgnoringModifiers.length() > 0 ?
charsIgnoringModifiers.charAt(0) : KeyEvent.CHAR_UNDEFINED;
if (!useShiftedCharacter && charsIgnoringModifiersAndShift != null && charsIgnoringModifiersAndShift.length() > 0) {
testCharIgnoringModifiers = charsIgnoringModifiersAndShift.charAt(0);
}
int[] in = new int[] {testCharIgnoringModifiers, isDeadChar ? 1 : 0, modifierFlags, keyCode, /*useNationalLayouts*/ 0};
int useNationalLayouts = (KeyEventProcessing.useNationalLayouts && !isCyrillicKeyboardLayout()) ? 1 : 0;
int[] in = new int[] {testCharIgnoringModifiers, isDeadChar ? 1 : 0, modifierFlags, keyCode, useNationalLayouts};
int[] out = new int[3]; // [jkeyCode, jkeyLocation, deadChar]
postsTyped = NSEvent.nsToJavaKeyInfo(in, out);
@@ -480,7 +281,7 @@ final class CPlatformResponder {
NSEvent.nsToJavaEventType(eventType);
}
char javaChar = NSEvent.nsToJavaCharOld(testChar, modifierFlags);
char javaChar = NSEvent.nsToJavaChar(testChar, modifierFlags, spaceKeyTyped);
// Some keys may generate a KEY_TYPED, but we can't determine
// what that character is. That's likely a bug, but for now we
// just check for CHAR_UNDEFINED.
@@ -488,8 +289,6 @@ final class CPlatformResponder {
postsTyped = false;
}
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags);
long when = System.currentTimeMillis();
if (jeventType == KeyEvent.KEY_PRESSED) {

View File

@@ -220,8 +220,10 @@ public class CPlatformView extends CFRetainedResource {
}
}
private void deliverKeyEvent(NSEvent nsEvent) {
responder.handleKeyEvent(nsEvent);
private void deliverKeyEvent(NSEvent event) {
responder.handleKeyEvent(event.getType(), event.getModifierFlags(), event.getCharacters(),
event.getCharactersIgnoringModifiers(), event.getCharactersIgnoringModifiersAndShift(),
event.getKeyCode(), true, false);
}
/**

View File

@@ -95,7 +95,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
double x, double y, double w, double h);
private static native void nativeSetNSWindowMinMax(long nsWindowPtr, double minW, double minH, double maxW, double maxH);
private static native void nativePushNSWindowToBack(long nsWindowPtr);
private static native void nativePushNSWindowToFront(long nsWindowPtr);
private static native void nativePushNSWindowToFront(long nsWindowPtr, boolean wait);
private static native void nativeSetNSWindowTitle(long nsWindowPtr, String title);
private static native void nativeRevalidateNSWindowShadow(long nsWindowPtr);
private static native void nativeSetNSWindowMinimizedIcon(long nsWindowPtr, long nsImage);
@@ -532,6 +532,14 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
styleBits = SET(styleBits, DARK, Boolean.parseBoolean(prop.toString()));
}
prop = rootpane.getClientProperty(WINDOW_TRANSPARENT_TITLEBAR_APPEARANCE);
if (prop != null) {
boolean val = Boolean.parseBoolean(prop.toString());
styleBits = SET(styleBits, TRANSPARENT_TITLE_BAR, val);
styleBits = SET(styleBits, FULL_WINDOW_CONTENT, val);
styleBits = SET(styleBits, TITLE_VISIBLE, !val);
}
prop = rootpane.getClientProperty(WINDOW_LIGHT_APPEARANCE);
if (prop != null) {
styleBits = SET(styleBits, LIGHT, Boolean.parseBoolean(prop.toString()));
@@ -675,7 +683,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
@Override // PlatformWindow
public void setBounds(int x, int y, int w, int h) {
execute(ptr -> AWTThreading.executeWaitToolkit(() -> nativeSetNSWindowBounds(ptr, x, y, w, h)));
execute(ptr -> nativeSetNSWindowBounds(ptr, x, y, w, h));
}
public void setMaximizedBounds(int x, int y, int w, int h) {
@@ -911,7 +919,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
lwcToolkit.activateApplicationIgnoringOtherApps();
}
updateFocusabilityForAutoRequestFocus(false);
execute(CPlatformWindow::nativePushNSWindowToFront);
execute(ptr -> AWTThreading.executeWaitToolkit(wait -> nativePushNSWindowToFront(ptr, wait)));
updateFocusabilityForAutoRequestFocus(true);
}
@@ -1257,11 +1265,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
: SHOULD_BECOME_KEY | SHOULD_BECOME_MAIN;
}
private boolean isBlocked() {
LWWindowPeer blocker = (peer != null) ? peer.getBlocker() : null;
return (blocker != null);
}
/*
* An utility method for the support of the auto request focus.
* Updates the focusable state of the window under certain

View File

@@ -52,7 +52,7 @@ final public class CTaskbarPeer implements TaskbarPeer {
@Override
public void setProgressValue(int value) {
//Application.getApplication().setDockIconProgress(value);
Application.getApplication().setDockIconProgress(value);
}
@Override

View File

@@ -47,7 +47,9 @@ final class CWrapper {
// 'level' is one of the keys defined above
static native void setLevel(long window, int level);
static native void makeKeyAndOrderFront(long window);
static void makeKeyAndOrderFront(long window) {
AWTThreading.executeWaitToolkit(wait -> nativeMakeKeyAndOrderFront(window, wait));
}
static native void makeMainWindow(long window);
static native boolean canBecomeMainWindow(long window);
static native boolean isKeyWindow(long window);
@@ -62,10 +64,11 @@ final class CWrapper {
* @param window the pointer of the NSWindow
*/
static void orderOut(long window) {
AWTThreading.executeWaitToolkit(() -> nativeOrderOut(window));
AWTThreading.executeWaitToolkit(wait -> nativeOrderOut(window, wait));
}
private static native void nativeOrderOut(long window);
private static native void nativeOrderOut(long window, boolean wait);
private static native void nativeMakeKeyAndOrderFront(long window, boolean wait);
/**
* Removes the window from the screen and releases it. According to

View File

@@ -298,8 +298,7 @@ final class NSEvent {
* There is a small number of NS characters that need to be converted
* into other characters before we pass them to AWT.
*/
static native String nsToJavaChar(char nsChar, int modifierFlags, boolean spaceKeyTyped);
static native char nsToJavaCharOld(char nsChar, int modifierFlags);
static native char nsToJavaChar(char nsChar, int modifierFlags, boolean spaceKeyTyped);
static boolean isPopupTrigger(int jmodifiers) {
final boolean isRightButtonDown = ((jmodifiers & InputEvent.BUTTON3_DOWN_MASK) != 0);

View File

@@ -222,6 +222,7 @@ struct CharToVKEntry {
static const struct CharToVKEntry charToDeadVKTable[] = {
{0x0060, java_awt_event_KeyEvent_VK_DEAD_GRAVE},
{0x00B4, java_awt_event_KeyEvent_VK_DEAD_ACUTE},
{0xFFFF, java_awt_event_KeyEvent_VK_DEAD_ACUTE},
{0x0384, java_awt_event_KeyEvent_VK_DEAD_ACUTE}, // Unicode "GREEK TONOS" -- Greek keyboard, semicolon key
{0x005E, java_awt_event_KeyEvent_VK_DEAD_CIRCUMFLEX},
{0x007E, java_awt_event_KeyEvent_VK_DEAD_TILDE},
@@ -887,42 +888,20 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_NSEvent
* Method: nsToJavaChar
* Signature: (CI)Ljava/lang/String
*/
JNIEXPORT jstring JNICALL
Java_sun_lwawt_macosx_NSEvent_nsToJavaChar
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags, jboolean spaceKeyTyped)
{
jstring charAsString = NULL;
JNF_COCOA_ENTER(env);
NSString * nsStr = [NSString stringWithFormat: @"%C", nsChar];
charAsString = JNFNSToJavaString(env, nsStr);
JNF_COCOA_EXIT(env);
return charAsString;
}
/*
* Class: sun_lwawt_macosx_NSEvent
* Method: nsToJavaChar
* Signature: (CI)C
*/
JNIEXPORT jint JNICALL
Java_sun_lwawt_macosx_NSEvent_nsToJavaCharOld
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags)
Java_sun_lwawt_macosx_NSEvent_nsToJavaChar
(JNIEnv *env, jclass cls, jchar nsChar, jint modifierFlags, jboolean spaceKeyTyped)
{
jchar javaChar = 0;
JNF_COCOA_ENTER(env);
javaChar = NsCharToJavaChar(nsChar, modifierFlags, false);
javaChar = NsCharToJavaChar(nsChar, modifierFlags, spaceKeyTyped);
JNF_COCOA_EXIT(env);

View File

@@ -34,12 +34,15 @@
#import "AWTView.h"
#import "AWTWindow.h"
#import "JavaComponentAccessibility.h"
#import "JavaTextAccessibility.h"
#import "JavaStaticTextAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "GeomUtilities.h"
#import "CGLLayer.h"
#import "java_awt_event_KeyEvent.h"
// keyboard layout
static NSString *kbdLayout;
@interface AWTView()
@property (retain) CDropTarget *_dropTarget;
@property (retain) CDragSource *_dragSource;
@@ -371,6 +374,21 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
if (![self hasMarkedText] && !fInPressAndHold) {
[self deliverJavaKeyEventHelper: event];
}
// Workaround for 8020209: special case for "Cmd =" and "Cmd ."
// because Cocoa calls performKeyEquivalent twice for these keystrokes
NSUInteger modFlags = [event modifierFlags] &
(NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask);
if (modFlags == NSCommandKeyMask) {
NSString *eventChars = [event charactersIgnoringModifiers];
if ([eventChars length] == 1) {
unichar ch = [eventChars characterAtIndex:0];
if (ch == '=' || ch == '.' ||
ch == 0x044E) { // small cyrillic u
[[NSApp mainMenu] performKeyEquivalent: event];
return YES;
}
}
}
NSUInteger deviceIndependentModifierFlagsMask =
[event modifierFlags] & NSDeviceIndependentModifierFlagsMask;
@@ -504,10 +522,10 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
const UCKeyboardLayout *keyboardLayout = (UCKeyboardLayout*)CFDataGetBytePtr(keyLayoutPtr);
UInt32 isDeadKeyPressed;
UInt32 isDeadKeyPressed = 0;
UInt32 lengthOfBuffer = 8;
UniChar stringWithChars[lengthOfBuffer];
UniCharCount actualLength;
UniCharCount actualLength = 0;
OSStatus status = UCKeyTranslate(
keyboardLayout,
@@ -840,8 +858,8 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
- (NSString *)accessibleSelectedText
{
id focused = [self accessibilityFocusedUIElement];
if (![focused isKindOfClass:[JavaTextAccessibility class]]) return nil;
return [(JavaTextAccessibility *)focused accessibilitySelectedTextAttribute];
if (![focused respondsToSelector:@selector(accessibilitySelectedText)]) return nil;
return [focused accessibilitySelectedText];
}
// same as above, but converts to RTFD
@@ -860,8 +878,8 @@ extern bool isSystemShortcut_NextWindowInApplication(NSUInteger modifiersMask, N
- (BOOL)replaceAccessibleTextSelection:(NSString *)text
{
id focused = [self accessibilityFocusedUIElement];
if (![focused isKindOfClass:[JavaTextAccessibility class]]) return NO;
[(JavaTextAccessibility *)focused accessibilitySetSelectedTextAttribute:text];
if (![focused respondsToSelector:@selector(setAccessibilitySelectedText)]) return NO;
[focused setAccessibilitySelectedText:text];
return YES;
}
@@ -1123,8 +1141,16 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod");
NSUInteger utf16Length = [useString lengthOfBytesUsingEncoding:NSUTF16StringEncoding];
NSUInteger utf8Length = [useString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
BOOL aStringIsComplex = NO;
unichar codePoint = [useString characterAtIndex:0];
#ifdef IM_DEBUG
NSLog(@"insertText kbdlayout %@ ",(NSString *)kbdLayout);
#endif // IM_DEBUG
if ((utf16Length > 2) ||
((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:[useString characterAtIndex:0]])) {
((utf8Length > 1) && [self isCodePointInUnicodeBlockNeedingIMEvent:codePoint]) ||
((codePoint == 0x5c) && ([(NSString *)kbdLayout containsString:@"Kotoeri"]))) {
aStringIsComplex = YES;
}
@@ -1164,6 +1190,15 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod");
}
}
+ (void)keyboardInputSourceChanged:(NSNotification *)notification
{
#ifdef IM_DEBUG
NSLog(@"keyboardInputSourceChangeNotification received");
#endif
NSTextInputContext *curContxt = [NSTextInputContext currentInputContext];
kbdLayout = curContxt.selectedKeyboardInputSource;
}
- (void) doCommandBySelector:(SEL)aSelector
{
#ifdef IM_DEBUG
@@ -1458,7 +1493,7 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod");
jint index = JNFCallIntMethod(env, fInputMethodLOCKABLE, jm_characterIndexForPoint, (jint)flippedLocation.x, (jint)flippedLocation.y); // AWT_THREADING Safe (AWTRunLoopMode)
#ifdef IM_DEBUG
fprintf(stderr, "characterIndexForPoint returning %ld\n", index);
fprintf(stderr, "characterIndexForPoint returning %d\n", index);
#endif // IM_DEBUG
if (index == -1) {
@@ -1495,6 +1530,13 @@ JNF_CLASS_CACHE(jc_CInputMethod, "sun/lwawt/macosx/CInputMethod");
fInputMethodLOCKABLE = JNFNewGlobalRef(env, inputMethod);
else
fInputMethodLOCKABLE = NULL;
NSTextInputContext *curContxt = [NSTextInputContext currentInputContext];
kbdLayout = curContxt.selectedKeyboardInputSource;
[[NSNotificationCenter defaultCenter] addObserver:[AWTView class]
selector:@selector(keyboardInputSourceChanged:)
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
}
- (void)abandonInput

View File

@@ -49,6 +49,7 @@
BOOL isMinimizing;
NSWindowTabbingMode javaWindowTabbingMode;
BOOL isEnterFullScreen;
BOOL isJustCreated;
}
// An instance of either AWTWindow_Normal or AWTWindow_Panel
@@ -66,6 +67,7 @@
@property (nonatomic) BOOL isMinimizing;
@property (nonatomic) NSWindowTabbingMode javaWindowTabbingMode;
@property (nonatomic) BOOL isEnterFullScreen;
@property (nonatomic) BOOL isJustCreated;
- (id) initWithPlatformWindow:(JNFWeakJObjectWrapper *)javaPlatformWindow
ownerWindow:owner

View File

@@ -303,6 +303,7 @@ AWT_NS_WINDOW_IMPLEMENTATION
@synthesize isMinimizing;
@synthesize javaWindowTabbingMode;
@synthesize isEnterFullScreen;
@synthesize isJustCreated;
- (void) updateMinMaxSize:(BOOL)resizable {
if (resizable) {
@@ -446,6 +447,7 @@ AWT_ASSERT_APPKIT_THREAD;
self.javaWindowTabbingMode = [self getJavaWindowTabbingMode];
self.isEnterFullScreen = NO;
self.isJustCreated = YES;
return self;
}
@@ -564,21 +566,6 @@ AWT_ASSERT_APPKIT_THREAD;
[super dealloc];
}
// Tests whether window is blocked by modal dialog/window
- (BOOL) isBlocked {
BOOL isBlocked = NO;
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
if (platformWindow != NULL) {
static JNF_MEMBER_CACHE(jm_isBlocked, jc_CPlatformWindow, "isBlocked", "()Z");
isBlocked = JNFCallBooleanMethod(env, platformWindow, jm_isBlocked) == JNI_TRUE ? YES : NO;
(*env)->DeleteLocalRef(env, platformWindow);
}
return isBlocked;
}
// Test whether window is simple window and owned by embedded frame
- (BOOL) isSimpleWindowOwnedByEmbeddedFrame {
BOOL isSimpleWindowOwnedByEmbeddedFrame = NO;
@@ -618,9 +605,8 @@ AWT_ASSERT_APPKIT_THREAD;
- (void) orderChildWindows:(BOOL)focus {
AWT_ASSERT_APPKIT_THREAD;
if (self.isMinimizing || [self isBlocked]) {
if (self.isMinimizing) {
// Do not perform any ordering, if iconify is in progress
// or the window is blocked by a modal window
return;
}
@@ -1046,21 +1032,6 @@ AWT_ASSERT_APPKIT_THREAD;
- (void)sendEvent:(NSEvent *)event {
if ([event type] == NSLeftMouseDown || [event type] == NSRightMouseDown || [event type] == NSOtherMouseDown) {
if ([self isBlocked]) {
// Move parent windows to front and make sure that a child window is displayed
// in front of its nearest parent.
if (self.ownerWindow != nil) {
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
if (platformWindow != NULL) {
static JNF_MEMBER_CACHE(jm_orderAboveSiblings, jc_CPlatformWindow, "orderAboveSiblings", "()V");
JNFCallVoidMethod(env,platformWindow, jm_orderAboveSiblings);
(*env)->DeleteLocalRef(env, platformWindow);
}
}
[self orderChildWindows:YES];
}
NSPoint p = [NSEvent mouseLocation];
NSRect frame = [self.nsWindow frame];
NSRect contentRect = [self.nsWindow contentRectForFrameRect:frame];
@@ -1222,6 +1193,11 @@ JNF_COCOA_ENTER(env);
nsWindow.contentView.frame = contentFrame;
resized = YES;
}
if (window.isJustCreated) {
// Perform Move/Resize event for just created windows
resized = YES;
window.isJustCreated = NO;
}
}
// resets the NSWindow's style mask if the mask intersects any of those bits
@@ -1334,7 +1310,7 @@ JNF_COCOA_ENTER(env);
// TODO: not sure we need displayIfNeeded message in our view
NSWindow *nsWindow = OBJC(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:YES block:^(){
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
@@ -1479,15 +1455,15 @@ JNF_COCOA_EXIT(env);
/*
* Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativePushNSWindowToFront
* Signature: (J)V
* Signature: (JZ)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativePushNSWindowToFront
(JNIEnv *env, jclass clazz, jlong windowPtr)
(JNIEnv *env, jclass clazz, jlong windowPtr, jboolean wait)
{
JNF_COCOA_ENTER(env);
NSWindow *nsWindow = OBJC(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[ThreadUtilities performOnMainThreadWaiting:(BOOL)wait block:^(){
if (![nsWindow isKeyWindow]) {
[nsWindow makeKeyAndOrderFront:nsWindow];

View File

@@ -35,6 +35,7 @@
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import "CPopupMenu.h"
#import "CMenuBar.h"
#import "ThreadUtilities.h"
#import "NSApplicationAWT.h"
@@ -824,3 +825,23 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env);
}
/*
* Class: com_apple_eawt__AppMenuBarHandler
* Method: nativeActivateDefaultMenuBar
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_com_apple_eawt__1AppMenuBarHandler_nativeActivateDefaultMenuBar
(JNIEnv *env, jclass clz, jlong cMenuBarPtr)
{
JNF_COCOA_ENTER(env);
CMenuBar *menu = (CMenuBar *)jlong_to_ptr(cMenuBarPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
if (menu) {
[CMenuBar activate:menu modallyDisabled:NO];
}
}];
JNF_COCOA_EXIT(env);
}

View File

@@ -169,44 +169,25 @@ canChooseDirectories:(BOOL)inChooseDirectories
[thePanel setAppearance:fOwner.appearance];
}
void (^onComplete)(BOOL, BOOL) = ^(BOOL responseOK, BOOL doStopModal) {
if (responseOK) {
NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
fURLs = (fMode == java_awt_FileDialog_LOAD)
? [openPanel URLs]
: [NSArray arrayWithObject:[openPanel URL]];
fPanelResult = [thePanel runModal];
fPanelResult = NSFileHandlingPanelOKButton;
} else {
fURLs = [NSArray array];
}
[fURLs retain];
if (doStopModal)
[NSApp stopModal];
if (menuBar != nil) {
[CMenuBar activate:menuBar modallyDisabled:NO];
}
};
[thePanel beginSheetModalForWindow:fOwner completionHandler:^(NSInteger result) {
onComplete(result == NSFileHandlingPanelOKButton, YES);
}];
[NSApp runModalForWindow:thePanel];
if (menuBar != nil) {
[CMenuBar activate:menuBar modallyDisabled:NO];
}
}
else
{
fPanelResult = [thePanel runModalForDirectory:fDirectory file:fFile];
}
if ([self userClickedOK]) {
if (fMode == java_awt_FileDialog_LOAD) {
NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
fURLs = [openPanel URLs];
} else {
fURLs = [NSArray arrayWithObject:[thePanel URL]];
}
[fURLs retain];
if ([self userClickedOK]) {
if (fMode == java_awt_FileDialog_LOAD) {
NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
fURLs = [openPanel URLs];
} else {
fURLs = [NSArray arrayWithObject:[thePanel URL]];
}
[fURLs retain];
}
[thePanel setDelegate:nil];

View File

@@ -38,6 +38,277 @@
#define NOT_A_CHECKBOXMENU -2
@interface CustomMenuItemView : NSView {
int16_t fireTimes;
BOOL isSelected;
NSSize shortcutSize;
NSSize textSize;
NSTrackingArea * trackingArea;
CMenuItem * owner;
}
@property (retain) NSString * keyShortcut;
@end
@implementation CustomMenuItemView
static CGFloat menuItemHeight = 18.f;
static CGFloat marginLeft = 20.f;
static CGFloat marginRight = 10.f;
static CGFloat gapTxtIcon = 5.f;
static CGFloat gapTxtShortcut = 23.f;
static NSFont * menuFont;
static NSFont * menuShortcutFont;
static NSColor * customBg = nil;
+ (void)initialize {
menuFont = [NSFont menuBarFontOfSize:(0)];
menuShortcutFont = [NSFont menuBarFontOfSize:(0)];
NSDictionary * attributes = [NSDictionary dictionaryWithObjectsAndKeys:menuFont, NSFontAttributeName, nil];
NSSize qSize = [[[[NSAttributedString alloc] initWithString:@"Q" attributes:attributes] autorelease] size];
// use empiric proportions (to look like default view)
menuItemHeight = qSize.height * 1.1f;
marginLeft = menuItemHeight * 1.1f;
marginRight = menuItemHeight * 0.55f;
gapTxtIcon = menuItemHeight * 0.27f;
gapTxtShortcut = menuItemHeight * 1.2f;
// Initialize custom bg color (for light theme with enabled accessibility.reduceTransparency)
// If we use transparent bg than we will see visual inconsistency
// And it seems that we can't obtain this color from system
NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
NSDictionary<NSString *,id> * dict = [defs persistentDomainForName:@"com.apple.universalaccess.plist"];
if (dict != nil) {
id reduceVal = [dict valueForKey:@"reduceTransparency"];
if (reduceVal != nil && [reduceVal isKindOfClass:[NSNumber class]] && [reduceVal intValue] != 0) {
NSString * mode = [defs stringForKey:@"AppleInterfaceStyle"];
if (mode == nil) { // light system theme
customBg = [NSColor colorWithCalibratedWhite:246.f/255 alpha:1.f];
[customBg retain];
// NSLog(@"\treduceTransparency is enabled (use custom background color for menu items)");
}
}
}
// NSLog(@"\tmenuItemHeight=%1.2f, marginLeft=%1.2f, marginRight=%1.2f, gapTxtIcon=%1.2f, gapTxtShortcut=%1.2f",
// menuItemHeight, marginLeft, marginRight, gapTxtIcon, gapTxtShortcut);
}
- (id)initWithOwner:(CMenuItem *)menuItem {
NSRect viewRect = NSMakeRect(0, 0, /* width autoresizes */ 1, menuItemHeight);
self = [super initWithFrame:viewRect];
if (self == nil) {
return self;
}
owner = menuItem;
self.autoresizingMask = NSViewWidthSizable;
self.keyShortcut = nil;
fireTimes = 0;
isSelected = NO;
trackingArea = nil;
shortcutSize = NSZeroSize;
textSize = NSZeroSize;
return self;
}
- (void)dealloc {
if(trackingArea != nil) {
[trackingArea release];
}
[super dealloc];
}
- (void)mouseEntered:(NSEvent*)event {
if ([owner isEnabled] && !isSelected) {
isSelected = YES;
[self setNeedsDisplay:YES];
}
}
- (void)mouseExited:(NSEvent *)event {
if (isSelected) {
isSelected = NO;
[self setNeedsDisplay:YES];
}
}
- (void)mouseUp:(NSEvent*)event {
if (![owner isEnabled])
return;
fireTimes = 0;
isSelected = !isSelected;
[self setNeedsDisplay:YES];
NSTimer *timer = [NSTimer timerWithTimeInterval:0.05 target:self selector:@selector(animateDismiss:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode];
}
-(void)updateTrackingAreas {
[super updateTrackingAreas];
if(trackingArea != nil) {
[self removeTrackingArea:trackingArea];
[trackingArea release];
}
int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
-(void)animateDismiss:(NSTimer *)aTimer {
if (fireTimes <= 2) {
isSelected = !isSelected;
[self setNeedsDisplay:YES];
} else {
[aTimer invalidate];
[self sendAction];
}
fireTimes++;
}
- (void)sendAction {
NSMenuItem * mi = owner.menuItem;
[NSApp sendAction:[mi action] to:[mi target] from:mi];
NSMenu *menu = [mi menu];
[menu cancelTracking];
// NOTE: we can also invoke handler directly [owner handleAction:[owner menuItem]];
}
//#define VISUAL_DEBUG_CUSTOM_ITEM_VIEW
- (void) drawRect:(NSRect)dirtyRect {
NSRect rectBounds = [self bounds];
NSString * text = owner.menuItem.title;
#ifdef VISUAL_DEBUG_CUSTOM_ITEM_VIEW
[[NSColor yellowColor] set];
NSFrameRectWithWidth([self bounds], 1.0f);
#endif // VISUAL_DEBUG_CUSTOM_ITEM_VIEW
const BOOL isEnabled = [owner isEnabled];
NSColor * textColor = [NSColor textColor];
NSColor * bgColor = customBg != nil ? customBg : [NSColor clearColor];
if (!isEnabled) {
textColor = [NSColor grayColor];
} else if (isSelected) {
if (@available(macOS 10.14, *)) {
bgColor = [NSColor controlAccentColor];
} else {
bgColor = [NSColor selectedControlColor];
}
textColor = [NSColor selectedMenuItemTextColor];
}
// 1. draw bg
[bgColor set];
NSRectFill(rectBounds);
// 2. draw icon if presented
CGFloat x = rectBounds.origin.x + marginLeft;
NSImage * image = owner.menuItem.image;
if (image != nil) {
NSRect imageBounds = rectBounds;
imageBounds.origin.x = x;
imageBounds.size.width = image.size.width;
[image drawInRect:imageBounds];
x += image.size.width + gapTxtIcon;
#ifdef VISUAL_DEBUG_CUSTOM_ITEM_VIEW
[[NSColor redColor] set];
NSFrameRectWithWidth(imageBounds, 1.0f);
#endif // VISUAL_DEBUG_CUSTOM_ITEM_VIEW
}
// 3. draw text
[textColor set];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
menuFont, NSFontAttributeName,
textColor, NSForegroundColorAttributeName,
nil];
NSRect txtBounds = rectBounds;
txtBounds.origin.x = x;
txtBounds.size.width = textSize.width;
[text drawInRect:txtBounds withAttributes:attributes];
#ifdef VISUAL_DEBUG_CUSTOM_ITEM_VIEW
[[NSColor blackColor] set];
NSFrameRectWithWidth(txtBounds, 1.0f);
#endif // VISUAL_DEBUG_CUSTOM_ITEM_VIEW
if (self.keyShortcut != nil) {
// 4.1 draw shortcut
NSRect keyBounds = rectBounds;
keyBounds.origin.x = keyBounds.size.width - marginRight - shortcutSize.width;
keyBounds.size.width = shortcutSize.width;
NSDictionary *keyAttr = [NSDictionary dictionaryWithObjectsAndKeys:
menuShortcutFont, NSFontAttributeName,
textColor, NSForegroundColorAttributeName,
nil];
[self.keyShortcut drawInRect:keyBounds withAttributes:keyAttr];
#ifdef VISUAL_DEBUG_CUSTOM_ITEM_VIEW
[[NSColor magentaColor] set];
NSFrameRectWithWidth(keyBounds, 1.0f);
#endif // VISUAL_DEBUG_CUSTOM_ITEM_VIEW
} else {
if ([owner isKindOfClass:CMenu.class]) {
// 4.2 draw arrow-image of submenu
NSImage *arrow = [NSImage imageNamed:NSImageNameRightFacingTriangleTemplate]; // TODO: use correct triangle image
NSRect arrowBounds = rectBounds;
arrowBounds.origin.x = rectBounds.size.width - marginRight - arrow.size.width;
arrowBounds.origin.y = rectBounds.origin.y + (rectBounds.size.height - arrow.size.height) / 2;
arrowBounds.size = arrow.size;
[arrow drawInRect:arrowBounds];
#ifdef VISUAL_DEBUG_CUSTOM_ITEM_VIEW
[[NSColor magentaColor] set];
NSFrameRectWithWidth(arrowBounds, 1.0f);
#endif // VISUAL_DEBUG_CUSTOM_ITEM_VIEW
}
}
}
- (void)recalcSizes {
NSString * text = owner.menuItem.title;
NSImage * image = owner.menuItem.image;
NSDictionary * attributes = [NSDictionary dictionaryWithObjectsAndKeys:menuFont, NSFontAttributeName, nil];
textSize = [[[[NSAttributedString alloc] initWithString:text attributes:attributes] autorelease] size];
NSSize resultSize = NSMakeSize(textSize.width + marginLeft + marginRight, menuItemHeight);
if (image != nil) {
NSSize imgSize = image.size;
resultSize.width += imgSize.width + gapTxtIcon;
}
if (self.keyShortcut != nil) {
NSDictionary * ksa = [NSDictionary dictionaryWithObjectsAndKeys:menuShortcutFont, NSFontAttributeName, nil];
shortcutSize = [[[[NSAttributedString alloc] initWithString:self.keyShortcut attributes:ksa] autorelease] size];
resultSize.width += shortcutSize.width + gapTxtShortcut;
}
[self.widthAnchor constraintGreaterThanOrEqualToConstant:resultSize.width].active = YES;
}
@end
@implementation CMenuItem
@@ -140,6 +411,20 @@
}
- (void) setAcceleratorText:(NSString *)acceleratorText {
if ([acceleratorText isEqualToString:@""]) {
acceleratorText = nil;
}
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
CustomMenuItemView *menuItemView = fMenuItem.view;
if (menuItemView == nil) {
fMenuItem.view = menuItemView = [[[CustomMenuItemView alloc] initWithOwner:self] autorelease];
}
menuItemView.keyShortcut = acceleratorText;
[menuItemView recalcSizes];
}];
}
- (void) setJavaLabel:(NSString *)theLabel shortcut:(NSString *)theKeyEquivalent modifierMask:(jint)modifiers {
NSUInteger modifierMask = 0;
@@ -166,13 +451,18 @@
[fMenuItem setKeyEquivalent:theKeyEquivalent];
[fMenuItem setKeyEquivalentModifierMask:modifierMask];
[fMenuItem setTitle:theLabel];
if ([fMenuItem.view isKindOfClass:CustomMenuItemView.class]) {
[(CustomMenuItemView *)fMenuItem.view recalcSizes];
}
}];
}
- (void) setJavaImage:(NSImage *)theImage {
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[fMenuItem setImage:theImage];
if ([fMenuItem.view isKindOfClass:CustomMenuItemView.class]) {
[(CustomMenuItemView *)fMenuItem.view recalcSizes];
}
}];
}
@@ -183,7 +473,6 @@
}];
}
- (void)setJavaEnabled:(BOOL) enabled {
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
@@ -358,6 +647,21 @@ Java_sun_lwawt_macosx_CMenuItem_nativeSetLabel
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CMenuItem
* Method: nativeSetAcceleratorText
* Signature: (JLjava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeSetAcceleratorText
(JNIEnv *env, jobject peer, jlong menuItemObj, jstring acceleratorText)
{
JNF_COCOA_ENTER(env);
NSString *theText = JNFJavaToNSString(env, acceleratorText);
[((CMenuItem *)jlong_to_ptr(menuItemObj)) setAcceleratorText:theText];
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CMenuItem
* Method: nativeSetTooltip

View File

@@ -29,12 +29,12 @@
/*
* Class: sun_lwawt_macosx_CWrapper$NSWindow
* Method: makeKeyAndOrderFront
* Signature: (J)V
* Method: nativeMakeKeyAndOrderFront
* Signature: (JZ)V
*/
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CWrapper_00024NSWindow_makeKeyAndOrderFront
(JNIEnv *env, jclass cls, jlong windowPtr)
Java_sun_lwawt_macosx_CWrapper_00024NSWindow_nativeMakeKeyAndOrderFront
(JNIEnv *env, jclass cls, jlong windowPtr, jboolean wait)
{
JNF_COCOA_ENTER(env);
@@ -42,7 +42,7 @@ JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThread:@selector(makeKeyAndOrderFront:)
on:window
withObject:nil
waitUntilDone:NO];
waitUntilDone:(BOOL)wait];
JNF_COCOA_EXIT(env);
}
@@ -136,11 +136,11 @@ JNF_COCOA_EXIT(env);
/*
* Class: sun_lwawt_macosx_CWrapper$NSWindow
* Method: nativeOrderOut
* Signature: (J)V
* Signature: (JZ)V
*/
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CWrapper_00024NSWindow_nativeOrderOut
(JNIEnv *env, jclass cls, jlong windowPtr)
(JNIEnv *env, jclass cls, jlong windowPtr, jboolean wait)
{
JNF_COCOA_ENTER(env);
@@ -148,7 +148,7 @@ JNF_COCOA_ENTER(env);
[ThreadUtilities performOnMainThread:@selector(orderOut:)
on:window
withObject:window
waitUntilDone:YES];
waitUntilDone:(BOOL)wait];
JNF_COCOA_EXIT(env);
}

View File

@@ -14,7 +14,6 @@
#import "JavaBaseAccessibility.h"
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "JavaTextAccessibility.h"
#import "JavaListAccessibility.h"
#import "JavaTableAccessibility.h"
#import "JavaListRowAccessibility.h"
@@ -22,6 +21,11 @@
#import "JavaCellAccessibility.h"
#import "JavaOutlineAccessibility.h"
#import "JavaOutlineRowAccessibility.h"
#import "JavaStaticTextAccessibility.h"
#import "JavaNavigableTextAccessibility.h"
#import "JavaScrollAreaAccessibility.h"
#import "JavaTabGroupAccessibility.h"
#import "JavaComboBoxAccessibility.h"
#import "JavaComponentAccessibility.h"
#import "ThreadUtilities.h"
#import "AWTView.h"
@@ -239,7 +243,7 @@ static jobject sAccessibilityClass = NULL;
{
if ([parent isKindOfClass:[JavaTableAccessibility class]]) {
if (whichChildren == JAVA_AX_SELECTED_CHILDREN) {
NSArray<NSNumber *> *selectedRowIndexses = [parent selectedAccessibleRows];
NSArray<NSNumber *> *selectedRowIndexses = [(JavaTableAccessibility *)parent selectedAccessibleRows];
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[selectedRowIndexses count]];
for (NSNumber *index in selectedRowIndexses) {
[children addObject:[[JavaTableRowAccessibility alloc] initWithParent:parent
@@ -251,7 +255,7 @@ static jobject sAccessibilityClass = NULL;
}
return [NSArray arrayWithArray:children];
} else if (whichChildren == JAVA_AX_ALL_CHILDREN) {
int rowCount = [parent accessibleRowCount];
int rowCount = [(JavaTableAccessibility *)parent accessibleRowCount];
NSMutableArray *children = [NSMutableArray arrayWithCapacity:rowCount];
for (int i = 0; i < rowCount; i++) {
[children addObject:[[JavaTableRowAccessibility alloc] initWithParent:parent
@@ -370,19 +374,23 @@ static jobject sAccessibilityClass = NULL;
} else if ([parent isKindOfClass:[JavaOutlineAccessibility class]]) {
newChild = [JavaOutlineRowAccessibility alloc];
} else if ([javaRole isEqualToString:@"pagetablist"]) {
newChild = [TabGroupAccessibility alloc];
newChild = [JavaTabGroupAccessibility alloc];
} else if ([javaRole isEqualToString:@"scrollpane"]) {
newChild = [ScrollAreaAccessibility alloc];
newChild = [JavaScrollAreaAccessibility alloc];
} else {
NSString *nsRole = [sRoles objectForKey:javaRole];
if ([nsRole isEqualToString:NSAccessibilityStaticTextRole] || [nsRole isEqualToString:NSAccessibilityTextAreaRole] || [nsRole isEqualToString:NSAccessibilityTextFieldRole]) {
newChild = [JavaTextAccessibility alloc];
if ([nsRole isEqualToString:NSAccessibilityStaticTextRole]) {
newChild = [JavaStaticTextAccessibility alloc];
} else if ([nsRole isEqualToString:NSAccessibilityTextAreaRole] || [nsRole isEqualToString:NSAccessibilityTextFieldRole]) {
newChild = [JavaNavigableTextAccessibility alloc];
} else if ([nsRole isEqualToString:NSAccessibilityListRole]) {
newChild = [JavaListAccessibility alloc];
} else if ([nsRole isEqualToString:NSAccessibilityTableRole]) {
newChild = [JavaTableAccessibility alloc];
} else if ([nsRole isEqualToString:NSAccessibilityOutlineRole]) {
newChild = [JavaOutlineAccessibility alloc];
} else if ([nsRole isEqualToString:NSAccessibilityComboBoxRole]) {
newChild = [JavaComboBoxAccessibility alloc];
} else {
newChild = [JavaComponentAccessibility alloc];
}

View File

@@ -0,0 +1,14 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaElementAccessibility.h"
@interface JavaComboBoxAccessibility : JavaElementAccessibility
@property(readonly) NSString *accessibleSelectedText;
- (void)accessibleShowMenu;
@end
@interface PlatformAxComboBox : PlatformAxElement
@end

View File

@@ -0,0 +1,75 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaComboBoxAccessibility.h"
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
static const char* ACCESSIBLE_JCOMBOBOX_NAME = "javax.swing.JComboBox$AccessibleJComboBox";
@implementation JavaComboBoxAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxComboBox";
}
- (NSString *)accessibleSelectedText {
JNIEnv *env = [ThreadUtilities getJNIEnv];
JNFClassInfo clsInfo;
clsInfo.name = ACCESSIBLE_JCOMBOBOX_NAME;
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
JNF_MEMBER_CACHE(jm_getAccessibleSelection, clsInfo, "getAccessibleSelection", "(I)Ljavax/accessibility/Accessible;");
jobject axSelectedChild = JNFCallObjectMethod(env, [self axContextWithEnv:env], jm_getAccessibleSelection, 0);
if (axSelectedChild == NULL) {
return nil;
}
jobject childName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, axSelectedChild, fComponent);
if (childName == NULL) {
(*env)->DeleteLocalRef(env, axSelectedChild);
return nil;
}
NSString *selectedText = JNFObjectToString(env, childName);
(*env)->DeleteLocalRef(env, axSelectedChild);
(*env)->DeleteLocalRef(env, childName);
return selectedText;
}
- (void)accessibleShowMenu {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getAccessibleAction, sjc_CAccessibility, "getAccessibleAction", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleAction;");
// On MacOSX, text doesn't have actions, in java it does.
// cmcnote: NOT TRUE - Editable text has AXShowMenu. Textfields have AXConfirm. Static text has no actions.
jobject axAction = JNFCallStaticObjectMethod(env, jm_getAccessibleAction, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axAction != NULL) {
//+++gdb NOTE: In MacOSX, there is just a single Action, not multiple. In java,
// the first one seems to be the most basic, so this will be used.
// cmcnote: NOT TRUE - Sometimes there are multiple actions, eg sliders have AXDecrement AND AXIncrement (radr://3893192)
JavaAxAction *action = [[JavaAxAction alloc] initWithEnv:env withAccessibleAction:axAction withIndex:0 withComponent:fComponent];
[action perform];
[action release];
(*env)->DeleteLocalRef(env, axAction);
}
}
@end
@implementation PlatformAxComboBox
- (id)accessibilityValue {
return [(JavaComboBoxAccessibility *)[self javaBase] accessibleSelectedText];
}
- (BOOL)accessibilityPerformPress {
[(JavaComboBoxAccessibility *)[self javaBase] accessibleShowMenu];
return YES;
}
- (BOOL)isAccessibilityEnabled {
return YES;
}
@end

View File

@@ -104,44 +104,3 @@
- (id)accessibilityFocusedUIElement;
@end
@interface TabGroupAccessibility : JavaComponentAccessibility {
NSInteger _numTabs;
}
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext;
- (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount;
- (NSArray *)accessibilityChildrenAttribute;
- (id) accessibilityTabsAttribute;
- (BOOL)accessibilityIsTabsAttributeSettable;
- (NSArray *)accessibilityContentsAttribute;
- (BOOL)accessibilityIsContentsAttributeSettable;
- (id) accessibilityValueAttribute;
@end
@interface TabGroupControlAccessibility : JavaComponentAccessibility {
jobject fTabGroupAxContext;
}
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole;
- (jobject)tabGroup;
- (void)getActionsWithEnv:(JNIEnv *)env;
- (id)accessibilityValueAttribute;
@end
@interface ScrollAreaAccessibility : JavaComponentAccessibility {
}
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
- (NSArray *)accessibilityContentsAttribute;
- (BOOL)accessibilityIsContentsAttributeSettable;
- (id)accessibilityVerticalScrollBarAttribute;
- (BOOL)accessibilityIsVerticalScrollBarAttributeSettable;
- (id)accessibilityHorizontalScrollBarAttribute;
- (BOOL)accessibilityIsHorizontalScrollBarAttributeSettable;
@end

View File

@@ -42,7 +42,7 @@
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "JavaTextAccessibility.h"
#import "JavaStaticTextAccessibility.h"
#import "ThreadUtilities.h"
#import "AWTView.h"
@@ -582,7 +582,8 @@ static NSObject *sAttributeNamesLOCK = nil;
// The sRoles NSMutableDictionary maps popupmenu to Mac's popup button.
// JComboBox behavior currently relies on this. However this is not the
// proper mapping for a JPopupMenu so fix that.
if ( [javaRole isEqualToString:@"popupmenu"] &&
if ([[self parent] isKindOfClass:[JavaBaseAccessibility class]] &&
[javaRole isEqualToString:@"popupmenu"] &&
![[[self parent] javaRole] isEqualToString:@"combobox"] ) {
fNSRole = NSAccessibilityMenuRole;
}
@@ -948,390 +949,3 @@ static NSObject *sAttributeNamesLOCK = nil;
}
@end
@implementation TabGroupAccessibility
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withView:(NSView *)view withJavaRole:(NSString *)javaRole
{
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
if (self) {
_numTabs = -1; //flag for uninitialized numTabs
}
return self;
}
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
{
NSMutableArray *names = (NSMutableArray *)[super initializeAttributeNamesWithEnv:env];
[names addObject:NSAccessibilityTabsAttribute];
[names addObject:NSAccessibilityContentsAttribute];
[names addObject:NSAccessibilityValueAttribute];
return names;
}
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext
{
NSArray *tabs = [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
// Looking at the JTabbedPane sources, there is always one AccessibleSelection.
jobject selAccessible = getAxContextSelection(env, axContext, 0, fComponent);
if (selAccessible == NULL) return nil;
// Go through the tabs and find selAccessible
_numTabs = [tabs count];
JavaComponentAccessibility *aTab;
NSInteger i;
for (i = 0; i < _numTabs; i++) {
aTab = (JavaComponentAccessibility *)[tabs objectAtIndex:i];
if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) {
(*env)->DeleteLocalRef(env, selAccessible);
return aTab;
}
}
(*env)->DeleteLocalRef(env, selAccessible);
return nil;
}
- (NSArray *)tabControlsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored
{
jobjectArray jtabsAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
if(jtabsAndRoles == NULL) return nil;
jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles);
if (arrayLen == 0) {
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return nil;
}
NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)];
// all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs
jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1.
if (jtabJavaRole == NULL) {
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return nil;
}
jobject jkey = JNFGetObjectField(env, jtabJavaRole, sjf_key);
NSString *tabJavaRole = JNFJavaToNSString(env, jkey);
(*env)->DeleteLocalRef(env, jkey);
NSInteger i;
NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly
for(i = 0; i < arrayLen; i+=2) {
jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i);
JavaComponentAccessibility *tab = [[[TabGroupControlAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease];
(*env)->DeleteLocalRef(env, jtab);
[tabs addObject:tab];
tabIndex++;
}
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return tabs;
}
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored
{
// Contents are the children of the selected tab.
id currentTab = [self currentTabWithEnv:env withAxContext:axContext];
if (currentTab == nil) return nil;
NSArray *contents = [JavaComponentAccessibility childrenOfParent:currentTab withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
if ([contents count] <= 0) return nil;
return contents;
}
- (id) accessibilityTabsAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
id tabs = [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
(*env)->DeleteLocalRef(env, axContext);
return tabs;
}
- (BOOL)accessibilityIsTabsAttributeSettable
{
return NO; //cmcnote: not sure.
}
- (NSInteger)numTabs
{
if (_numTabs == -1) {
_numTabs = [[self accessibilityTabsAttribute] count];
}
return _numTabs;
}
- (NSArray *) accessibilityContentsAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
(*env)->DeleteLocalRef(env, axContext);
return cont;
}
- (BOOL)accessibilityIsContentsAttributeSettable
{
return NO;
}
// axValue is the currently selected tab
-(id) accessibilityValueAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
id val = [self currentTabWithEnv:env withAxContext:axContext];
(*env)->DeleteLocalRef(env, axContext);
return val;
}
- (BOOL)accessibilityIsValueAttributeSettable
{
return YES;
}
- (void)accessibilitySetValueAttribute:(id)value //cmcnote: not certain this is ever actually called. investigate.
{
// set the current tab
NSNumber *number = (NSNumber *)value;
if (![number boolValue]) return;
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
setAxContextSelection(env, axContext, fIndex, fComponent);
(*env)->DeleteLocalRef(env, axContext);
}
- (NSArray *)accessibilityChildrenAttribute
{
//children = AXTabs + AXContents
NSArray *tabs = [self accessibilityTabsAttribute];
NSArray *contents = [self accessibilityContentsAttribute];
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[tabs count] + [contents count]];
[children addObjectsFromArray:tabs];
[children addObjectsFromArray:contents];
return (NSArray *)children;
}
// Without this optimization accessibilityChildrenAttribute is called in order to get the entire array of children.
// See similar optimization in JavaComponentAccessibility. We have to extend the base implementation here, since
// children of tabs are AXTabs + AXContents
- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount {
NSArray *result = nil;
if ( (maxCount == 1) && [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
// Children codes for ALL, SELECTED, VISIBLE are <0. If the code is >=0, we treat it as an index to a single child
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
//children = AXTabs + AXContents
NSArray *children = [self tabControlsWithEnv:env withTabGroupAxContext:axContext withTabCode:index allowIgnored:NO]; // first look at the tabs
if ([children count] > 0) {
result = children;
} else {
children= [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:(index-[self numTabs]) allowIgnored:NO];
if ([children count] > 0) {
result = children;
}
}
(*env)->DeleteLocalRef(env, axContext);
} else {
result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
}
return result;
}
@end
static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
@implementation TabGroupControlAccessibility
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole
{
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
if (self) {
if (tabGroup != NULL) {
fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroup);
} else {
fTabGroupAxContext = NULL;
}
}
return self;
}
- (void)dealloc
{
JNIEnv *env = [ThreadUtilities getJNIEnvUncached];
if (fTabGroupAxContext != NULL) {
JNFDeleteWeakGlobalRef(env, fTabGroupAxContext);
fTabGroupAxContext = NULL;
}
[super dealloc];
}
- (id)accessibilityValueAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent);
// Returns the current selection of the page tab list
id val = [NSNumber numberWithBool:ObjectEquals(env, axContext, selAccessible, fComponent)];
(*env)->DeleteLocalRef(env, selAccessible);
(*env)->DeleteLocalRef(env, axContext);
return val;
}
- (void)getActionsWithEnv:(JNIEnv *)env
{
TabGroupAction *action = [[TabGroupAction alloc] initWithEnv:env withTabGroup:[self tabGroup] withIndex:fIndex withComponent:fComponent];
[fActions setObject:action forKey:NSAccessibilityPressAction];
[action release];
}
- (jobject)tabGroup
{
if (fTabGroupAxContext == NULL) {
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject tabGroupAxContext = [(JavaComponentAccessibility *)[self parent] axContextWithEnv:env];
fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroupAxContext);
(*env)->DeleteLocalRef(env, tabGroupAxContext);
}
return fTabGroupAxContext;
}
@end
@implementation ScrollAreaAccessibility
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
{
NSMutableArray *names = (NSMutableArray *)[super initializeAttributeNamesWithEnv:env];
[names addObject:NSAccessibilityHorizontalScrollBarAttribute];
[names addObject:NSAccessibilityVerticalScrollBarAttribute];
[names addObject:NSAccessibilityContentsAttribute];
return names;
}
- (id)accessibilityHorizontalScrollBarAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;
// The scroll bars are in the children.
NSObject *aElement;
NSEnumerator *enumerator = [children objectEnumerator];
while ((aElement = [enumerator nextObject])) {
if ([aElement respondsToSelector:@selector(accessibilityRoleAttribute)]) {
if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [((NSObject <JavaBaseProvider> *)aElement).javaBase axContextWithEnv:env];
if (isHorizontal(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
}
(*env)->DeleteLocalRef(env, elementAxContext);
}
}
}
return nil;
}
- (BOOL)accessibilityIsHorizontalScrollBarAttributeSettable
{
return NO;
}
- (id)accessibilityVerticalScrollBarAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;
// The scroll bars are in the children.
NSEnumerator *enumerator = [children objectEnumerator];
JavaComponentAccessibility *aElement;
while ((aElement = (JavaComponentAccessibility *)[enumerator nextObject])) {
if ([[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [aElement axContextWithEnv:env];
if (isVertical(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
}
(*env)->DeleteLocalRef(env, elementAxContext);
}
}
return nil;
}
- (BOOL)accessibilityIsVerticalScrollBarAttributeSettable
{
return NO;
}
- (NSArray *)accessibilityContentsAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaComponentAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;
NSArray *contents = [NSMutableArray arrayWithCapacity:[children count]];
// The scroll bars are in the children. children less the scroll bars is the contents
NSEnumerator *enumerator = [children objectEnumerator];
NSObject *aElement;
while ((aElement = [enumerator nextObject])) {
if ([aElement respondsToSelector:@selector(accessibilityRoleAttribute)]) {
if (![[aElement accessibilityRoleAttribute] isEqualToString:NSAccessibilityScrollBarRole]) {
// no scroll bars in contents
[(NSMutableArray *) contents addObject:aElement];
}
}
}
return contents;
}
- (BOOL)accessibilityIsContentsAttributeSettable
{
return NO;
}
@end
/*
* Returns Object.equals for the two items
* This may use LWCToolkit.invokeAndWait(); don't call while holding fLock
* and try to pass a component so the event happens on the correct thread.
*/
static JNF_CLASS_CACHE(sjc_Object, "java/lang/Object");
static BOOL ObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component)
{
static JNF_MEMBER_CACHE(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z");
if ((a == NULL) && (b == NULL)) return YES;
if ((a == NULL) || (b == NULL)) return NO;
if (pthread_main_np() != 0) {
// If we are on the AppKit thread
static JNF_CLASS_CACHE(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit");
static JNF_STATIC_MEMBER_CACHE(jm_doEquals, sjc_LWCToolkit, "doEquals", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z");
return JNFCallStaticBooleanMethod(env, jm_doEquals, a, b, component); // AWT_THREADING Safe (AWTRunLoopMode)
}
return JNFCallBooleanMethod(env, a, jm_equals, b); // AWT_THREADING Safe (!appKit)
}

View File

@@ -5,6 +5,7 @@
#import "ThreadUtilities.h"
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleDescription, sjc_CAccessibility, "getAccessibleDescription", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
static JNF_CLASS_CACHE(sjc_CAccessible, "sun/lwawt/macosx/CAccessible");
static JNF_MEMBER_CACHE(jm_getAccessibleContext, sjc_CAccessible, "getAccessibleContext", "()Ljavax/accessibility/AccessibleContext;");
@@ -50,6 +51,15 @@ static void RaiseMustOverrideException(NSString *method)
return str;
}
- (NSString *)accessibilityHelp {
// RaiseMustOverrideException(@"accessibilityLabel");
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleDescription, [javaBase accessible], [javaBase component]);
NSString* str = JNFJavaToNSString(env, axName);
(*env)->DeleteLocalRef(env, axName);
return str;
}
- (NSArray *)accessibilityChildren
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
@@ -85,8 +95,9 @@ static void RaiseMustOverrideException(NSString *method)
- (id)accessibilityParent
{
JavaBaseAccessibility *parent = (JavaBaseAccessibility *) [self.javaBase parent];
return parent.platformAxElement;
id parent = [self.javaBase parent];
// Checking for protocol compliance can slow down at runtime. See: https://developer.apple.com/documentation/objectivec/nsobject/1418893-conformstoprotocol?language=objc
return [parent respondsToSelector:@selector(platformAxElement)] ? [parent platformAxElement] : parent;
}
- (BOOL)accessibilityIsIgnored
@@ -119,4 +130,8 @@ static void RaiseMustOverrideException(NSString *method)
return [[self javaBase] accessibilityIndexOfChild:child];
}
- (NSAccessibilityRole)accessibilityRole {
return [sRoles objectForKey:[[self javaBase] javaRole]];
}
@end

View File

@@ -4,7 +4,6 @@
#import "JavaListRowAccessibility.h"
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "JavaTextAccessibility.h"
#import "JavaListAccessibility.h"
#import "ThreadUtilities.h"

View File

@@ -0,0 +1,29 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaStaticTextAccessibility.h"
@interface JavaNavigableTextAccessibility : JavaStaticTextAccessibility
// protocol methods
- (NSValue *)accessibleBoundsForRange:(NSRange)range;
- (NSNumber *)accessibleLineForIndex:(NSInteger)index;
- (NSValue *)accessibleRangeForLine:(NSInteger)line;
- (NSString *)accessibleStringForRange:(NSRange)range;
- (NSValue *)accessibleRangeForIndex:(NSInteger)index;
- (NSValue *)accessibleRangeForPosition:(NSPoint)point;
@property(readonly) NSString *accessibleSelectedText;
@property(readonly) NSValue *accessibleSelectedTextRange;
@property(readonly) NSNumber *accessibleNumberOfCharacters;
@property(readonly) NSNumber *accessibleInsertionPointLineNumber;
@property(readonly) BOOL accessibleIsValueSettable;
@property(readonly) BOOL accessibleIsPasswordText;
- (void)accessibleSetSelectedText:(NSString *)accessibilitySelectedText;
- (void)accessibleSetSelectedTextRange:(NSRange)accessibilitySelectedTextRange;
@end
@interface PlatformAxNavigableText : PlatformAxStaticText <NSAccessibilityNavigableStaticText>
@end

View File

@@ -0,0 +1,267 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaNavigableTextAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
static JNF_CLASS_CACHE(sjc_CAccessibleText, "sun/lwawt/macosx/CAccessibleText");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleText, sjc_CAccessibility, "getAccessibleText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
@implementation JavaNavigableTextAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxNavigableText";
}
- (NSString *)accessibleValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
// cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return nil;
(*env)->DeleteLocalRef(env, axText);
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return nil;
static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;");
jobject jrange = JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent);
NSString *string = JNFJavaToNSString(env, jrange); // AWT_THREADING Safe (AWTRunLoop)
(*env)->DeleteLocalRef(env, jrange);
(*env)->DeleteLocalRef(env, axEditableText);
if (string == nil) string = @"";
return string;
}
- (NSValue *)accessibleBoundsForRange:(NSRange)range {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D");
jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (axBounds == NULL) return nil;
// We cheat because we know that the array is 4 elements long (x, y, width, height)
jdouble *values = (*env)->GetDoubleArrayElements(env, axBounds, 0);
if (values == NULL) {
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
NSLog(@"%s failed calling GetDoubleArrayElements", __FUNCTION__);
return nil;
};
NSRect bounds;
bounds.origin.x = values[0];
bounds.origin.y = [[[[self view] window] screen] frame].size.height - values[1] - values[3]; //values[1] is y-coord from top-left of screen. Flip. Account for the height (values[3]) when flipping
bounds.size.width = values[2];
bounds.size.height = values[3];
NSValue *result = [NSValue valueWithRect:bounds];
(*env)->ReleaseDoubleArrayElements(env, axBounds, values, 0);
return result;
}
- (NSNumber *)accessibleLineForIndex:(NSInteger)index {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return [NSNumber numberWithInt:row];
}
- (NSValue *)accessibleRangeForLine:(NSInteger)line {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, line); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaConvertIntArrayToNSRangeValue(env,axTextRange);
}
- (NSString *)accessibleStringForRange:(NSRange)range {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;");
jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (jstringForRange == NULL) return @"";
NSString* str = JNFJavaToNSString(env, jstringForRange);
(*env)->DeleteLocalRef(env, jstringForRange);
return str;
}
- (NSValue *)accessibleRangeForIndex:(NSInteger)index {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaConvertIntArrayToNSRangeValue(env, axTextRange);
}
- (NSValue *)accessibleRangeForPosition:(NSPoint)point {
point.y = [[[[self view] window] screen] frame].size.height - point.y; // flip into java screen coords (0 is at upper-left corner of screen)
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getCharacterIndexAtPosition, sjc_CAccessibleText, "getCharacterIndexAtPosition", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)I");
jint charIndex = JNFCallStaticIntMethod(env, jm_getCharacterIndexAtPosition, fAccessible, fComponent, point.x, point.y); // AWT_THREADING Safe (AWTRunLoop)
if (charIndex == -1) return nil;
// AccessibleText.getIndexAtPoint returns -1 for an invalid point
NSRange range = NSMakeRange(charIndex, 1); //range's length is 1 - one-character range
return [NSValue valueWithRange:range];
}
- (NSString *)accessibleSelectedText {
JNIEnv* env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return @"";
NSString* str = JNFJavaToNSString(env, axText);
(*env)->DeleteLocalRef(env, axText);
return str;
}
- (NSValue *)accessibleSelectedTextRange {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedTextRange, sjc_CAccessibleText, "getSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getSelectedTextRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaConvertIntArrayToNSRangeValue(env, axTextRange);
}
- (NSNumber *)accessibleNumberOfCharacters {
// cmcnote: should coalesce these two calls - radr://3951923
// also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
NSNumber* num = [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)];
(*env)->DeleteLocalRef(env, axText);
return num;
}
- (NSNumber *)accessibleInsertionPointLineNumber {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForInsertionPoint, sjc_CAccessibleText, "getLineNumberForInsertionPoint", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForInsertionPoint, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return [NSNumber numberWithInt:row];
}
- (BOOL)accessibleIsValueSettable {
// if text is enabled and editable, it's settable (according to NSCellTextAttributesAccessibility)
BOOL isEnabled = [(NSNumber *)[self accessibilityEnabledAttribute] boolValue];
if (!isEnabled) return NO;
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return NO;
(*env)->DeleteLocalRef(env, axEditableText);
return YES;
}
- (BOOL)accessibleIsPasswordText {
return [[self javaRole] isEqualToString:@"passwordtext"];
}
- (void)accessibleSetSelectedText:(NSString *)accessibilitySelectedText {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jstring jstringValue = JNFNSToJavaString(env, accessibilitySelectedText);
static JNF_STATIC_MEMBER_CACHE(jm_setSelectedText, sjc_CAccessibleText, "setSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;Ljava/lang/String;)V");
JNFCallStaticVoidMethod(env, jm_setSelectedText, fAccessible, fComponent, jstringValue); // AWT_THREADING Safe (AWTRunLoop)
}
- (void)accessibleSetSelectedTextRange:(NSRange)accessibilitySelectedTextRange {
jint startIndex = accessibilitySelectedTextRange.location;
jint endIndex = startIndex + accessibilitySelectedTextRange.length;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_setSelectedTextRange, sjc_CAccessibleText, "setSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)V");
JNFCallStaticVoidMethod(env, jm_setSelectedTextRange, fAccessible, fComponent, startIndex, endIndex); // AWT_THREADING Safe (AWTRunLoop)
}
@end
@implementation PlatformAxNavigableText
- (NSRect)accessibilityFrameForRange:(NSRange)range {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleBoundsForRange:range] rectValue];
}
- (NSInteger)accessibilityLineForIndex:(NSInteger)index {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleLineForIndex:index] integerValue];
}
- (NSRange)accessibilityRangeForLine:(NSInteger)line {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleRangeForLine:line] rangeValue];
}
- (NSString *)accessibilityStringForRange:(NSRange)range {
return [(JavaNavigableTextAccessibility *)[self javaBase] accessibleStringForRange:range];
}
- (id)accessibilityValue {
return [(JavaNavigableTextAccessibility *)[self javaBase] accessibleValue];
}
- (NSAccessibilitySubrole)accessibilitySubrole {
if ([(JavaNavigableTextAccessibility *)[self javaBase] accessibleIsPasswordText]) {
return NSAccessibilitySecureTextFieldSubrole;
}
return nil;
}
- (NSRange)accessibilityRangeForIndex:(NSInteger)index {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleRangeForIndex:index] rangeValue];
}
- (NSAccessibilityRole)accessibilityRole {
return [sRoles objectForKey:[self javaBase].javaRole];
}
- (NSRange)accessibilityRangeForPosition:(NSPoint)point {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleRangeForPosition:point] rangeValue];
}
- (NSString *)accessibilitySelectedText {
return [(JavaNavigableTextAccessibility *)[self javaBase] accessibleSelectedText];
}
- (NSRange)accessibilitySelectedTextRange {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleSelectedTextRange] rangeValue];
}
- (NSInteger)accessibilityNumberOfCharacters {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleNumberOfCharacters] integerValue];
}
- (NSInteger)accessibilityInsertionPointLineNumber {
return [[(JavaNavigableTextAccessibility *)[self javaBase] accessibleInsertionPointLineNumber] integerValue];
}
- (void)setAccessibilitySelectedText:(NSString *)accessibilitySelectedText {
[(JavaNavigableTextAccessibility *)[self javaBase] accessibleSetSelectedText:accessibilitySelectedText];
}
- (void)setAccessibilitySelectedTextRange:(NSRange)accessibilitySelectedTextRange {
[(JavaNavigableTextAccessibility *)[self javaBase] accessibleSetSelectedTextRange:accessibilitySelectedTextRange];
}
- (BOOL)isAccessibilityEdited {
return YES;
}
- (BOOL)isAccessibilityEnabled {
return YES;
}
/*
* Other text methods
- (NSRange)accessibilitySharedCharacterRange;
- (NSArray *)accessibilitySharedTextUIElements;
- (NSData *)accessibilityRTFForRange:(NSRange)range;
- (NSRange)accessibilityStyleRangeForIndex:(NSInteger)index;
*/
@end

View File

@@ -0,0 +1,14 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaElementAccessibility.h"
@interface JavaScrollAreaAccessibility : JavaElementAccessibility
@property(readonly) NSArray *accessibleContents;
@property(readonly) id accessibleVerticalScrollBar;
@property(readonly) id accessibleHorizontalScrollBar;
@end
@interface PlatformAxScrollArea : PlatformAxElement
@end

View File

@@ -0,0 +1,100 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaScrollAreaAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import "JavaComponentAccessibility.h"
@implementation JavaScrollAreaAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxScrollArea";
}
- (NSArray *)accessibleContents {
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaBaseAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;
NSArray *contents = [NSMutableArray arrayWithCapacity:[children count]];
// The scroll bars are in the children. children less the scroll bars is the contents
NSEnumerator *enumerator = [children objectEnumerator];
id aElement;
while ((aElement = [enumerator nextObject])) {
NSString *nsRole = [aElement isKindOfClass:[JavaComponentAccessibility class]] ? [aElement accessibilityRoleAttribute] : [aElement accessibilityRole]; // todo: Remove this solution when JavaComponentAccessibility is removed
if (![nsRole isEqualToString:NSAccessibilityScrollBarRole]) {
// no scroll bars in contents
[(NSMutableArray *) contents addObject:aElement];
}
}
return contents;
}
- (id)accessibleVerticalScrollBar {
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaBaseAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;
// The scroll bars are in the children.
NSEnumerator *enumerator = [children objectEnumerator];
id aElement;
while ((aElement = (PlatformAxElement *)[enumerator nextObject])) {
NSString *nsRole = [aElement isKindOfClass:[JavaComponentAccessibility class]] ? [aElement accessibilityRoleAttribute] : [aElement accessibilityRole]; // todo: Remove this solution when JavaComponentAccessibility is removed
if ([nsRole isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [[aElement javaBase] axContextWithEnv:env];
if (isVertical(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
}
(*env)->DeleteLocalRef(env, elementAxContext);
}
}
return nil;
}
- (id)accessibleHorizontalScrollBar {
JNIEnv *env = [ThreadUtilities getJNIEnv];
NSArray *children = [JavaBaseAccessibility childrenOfParent:self withEnv:env withChildrenCode:JAVA_AX_ALL_CHILDREN allowIgnored:YES];
if ([children count] <= 0) return nil;
// The scroll bars are in the children.
id aElement;
NSEnumerator *enumerator = [children objectEnumerator];
while ((aElement = [enumerator nextObject])) {
NSString *nsRole = [aElement isKindOfClass:[JavaComponentAccessibility class]] ? [aElement accessibilityRoleAttribute] : [aElement accessibilityRole]; // todo: Remove this solution when JavaComponentAccessibility is removed
if ([nsRole isEqualToString:NSAccessibilityScrollBarRole]) {
jobject elementAxContext = [[aElement javaBase] axContextWithEnv:env];
if (isHorizontal(env, elementAxContext, fComponent)) {
(*env)->DeleteLocalRef(env, elementAxContext);
return aElement;
}
(*env)->DeleteLocalRef(env, elementAxContext);
}
}
return nil;
}
@end
@implementation PlatformAxScrollArea
- (NSArray *)accessibilityContents {
return [(JavaScrollAreaAccessibility *)[self javaBase] accessibleContents];
}
- (id)accessibilityVerticalScrollBar {
return [(JavaScrollAreaAccessibility *)[self javaBase] accessibleVerticalScrollBar];
}
- (id)accessibilityHorizontalScrollBar {
return [(JavaScrollAreaAccessibility *)[self javaBase] accessibleHorizontalScrollBar];
}
@end

View File

@@ -0,0 +1,19 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaElementAccessibility.h"
@interface JavaStaticTextAccessibility : JavaElementAccessibility
/*
* Converts an int array to an NSRange wrapped inside an NSValue
* takes [start, end] values and returns [start, end - start]
*/
NSValue *javaConvertIntArrayToNSRangeValue(JNIEnv* env, jintArray array);
@property(readonly) NSString *accessibleValue;
@property(readonly) NSValue *accessibleVisibleCharacterRange;
@end
@interface PlatformAxStaticText : PlatformAxElement <NSAccessibilityStaticText>
@end

View File

@@ -0,0 +1,72 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaStaticTextAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
static JNF_CLASS_CACHE(sjc_CAccessibleText, "sun/lwawt/macosx/CAccessibleText");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleText, sjc_CAccessibility, "getAccessibleText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
@implementation JavaStaticTextAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxStaticText";
}
- (NSString *)accessibleValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axName != NULL) {
NSString* str = JNFJavaToNSString(env, axName);
(*env)->DeleteLocalRef(env, axName);
return str;
}
return @"";
}
- (NSValue *)accessibleVisibleCharacterRange {
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getVisibleCharacterRange, sjc_CAccessibleText, "getVisibleCharacterRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getVisibleCharacterRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaConvertIntArrayToNSRangeValue(env, axTextRange);
}
@end
@implementation PlatformAxStaticText
- (id)accessibilityValue {
return [(JavaStaticTextAccessibility *)[self javaBase] accessibleValue];
}
- (NSRect)accessibilityFrame {
return [super accessibilityFrame];
}
- (id)accessibilityParent {
return [super accessibilityParent];
}
- (NSRange)accessibilityVisibleCharacterRange {
return [[(JavaStaticTextAccessibility *)[self javaBase] accessibleVisibleCharacterRange] rangeValue];
}
@end
NSValue *javaConvertIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
jint *values = (*env)->GetIntArrayElements(env, array, 0);
if (values == NULL) {
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
NSLog(@"%s failed calling GetIntArrayElements", __FUNCTION__);
return nil;
};
NSValue *value = [NSValue valueWithRange:NSMakeRange(values[0], values[1] - values[0])];
(*env)->ReleaseIntArrayElements(env, array, values, 0);
return value;
}

View File

@@ -0,0 +1,19 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaElementAccessibility.h"
@interface JavaTabButtonAccessibility : JavaElementAccessibility {
jobject fTabGroupAxContext;
}
// from TabGroup controller
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole;
@property(readonly) jobject tabGroup;
@property(readonly) id accessibleValue;
- (void)performPressAction;
@end
@interface PlatformAxTabButton : PlatformAxElement
@end

View File

@@ -0,0 +1,93 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaTabButtonAccessibility.h"
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component);
@implementation JavaTabButtonAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxTabButton";
}
- (id)initWithParent:(NSObject *)parent withEnv:(JNIEnv *)env withAccessible:(jobject)accessible withIndex:(jint)index withTabGroup:(jobject)tabGroup withView:(NSView *)view withJavaRole:(NSString *)javaRole {
self = [super initWithParent:parent withEnv:env withAccessible:accessible withIndex:index withView:view withJavaRole:javaRole];
if (self) {
if (tabGroup != NULL) {
fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroup);
} else {
fTabGroupAxContext = NULL;
}
}
return self;
}
- (jobject)tabGroup {
if (fTabGroupAxContext == NULL) {
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject tabGroupAxContext = [(JavaBaseAccessibility *)[self parent] axContextWithEnv:env];
fTabGroupAxContext = JNFNewWeakGlobalRef(env, tabGroupAxContext);
(*env)->DeleteLocalRef(env, tabGroupAxContext);
}
return fTabGroupAxContext;
}
- (id)accessibleValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
jobject selAccessible = getAxContextSelection(env, [self tabGroup], fIndex, fComponent);
// Returns the current selection of the page tab list
id val = [NSNumber numberWithBool:javaObjectEquals(env, axContext, selAccessible, fComponent)];
(*env)->DeleteLocalRef(env, selAccessible);
(*env)->DeleteLocalRef(env, axContext);
return val;
}
- (void)performPressAction {
JNIEnv *env = [ThreadUtilities getJNIEnv];
TabGroupAction *action = [[TabGroupAction alloc] initWithEnv:env withTabGroup:[self tabGroup] withIndex:fIndex withComponent:fComponent];
[action perform];
[action release];
}
@end
@implementation PlatformAxTabButton
- (NSAccessibilitySubrole)accessibilitySubrole {
return NSAccessibilityTabButtonSubrole;
}
- (id)accessibilityValue {
return [(JavaTabButtonAccessibility *)[self javaBase] accessibleValue];
}
- (BOOL)accessibilityPerformPress {
[(JavaTabButtonAccessibility *)[self javaBase] performPressAction];
return YES;
}
@end
static JNF_CLASS_CACHE(sjc_Object, "java/lang/Object");
static BOOL javaObjectEquals(JNIEnv *env, jobject a, jobject b, jobject component) {
static JNF_MEMBER_CACHE(jm_equals, sjc_Object, "equals", "(Ljava/lang/Object;)Z");
if ((a == NULL) && (b == NULL)) return YES;
if ((a == NULL) || (b == NULL)) return NO;
if (pthread_main_np() != 0) {
// If we are on the AppKit thread
static JNF_CLASS_CACHE(sjc_LWCToolkit, "sun/lwawt/macosx/LWCToolkit");
static JNF_STATIC_MEMBER_CACHE(jm_doEquals, sjc_LWCToolkit, "doEquals", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/awt/Component;)Z");
return JNFCallStaticBooleanMethod(env, jm_doEquals, a, b, component); // AWT_THREADING Safe (AWTRunLoopMode)
}
return JNFCallBooleanMethod(env, a, jm_equals, b); // AWT_THREADING Safe (!appKit)
}

View File

@@ -0,0 +1,21 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaElementAccessibility.h"
@interface JavaTabGroupAccessibility : JavaElementAccessibility {
NSInteger _numTabs;
}
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext;
- (NSArray *)tabButtonsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored;
@property(readonly) NSArray *accessibleTabs;
@property(readonly) NSArray *accessibleContents;
@property(readonly) id accessibleValue;
@property(readonly) NSInteger numTabs;
@end
@interface PlatformAxTabGroup : PlatformAxElement
@end

View File

@@ -0,0 +1,179 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#import "JavaTabGroupAccessibility.h"
#import "JavaTabButtonAccessibility.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
#import <JavaNativeFoundation/JavaNativeFoundation.h>
static JNF_STATIC_MEMBER_CACHE(jm_getChildrenAndRoles, sjc_CAccessibility, "getChildrenAndRoles", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;IZ)[Ljava/lang/Object;");
@implementation JavaTabGroupAccessibility
- (NSString *)getPlatformAxElementClassName {
return @"PlatformAxTabGroup";
}
- (id)currentTabWithEnv:(JNIEnv *)env withAxContext:(jobject)axContext {
NSArray *tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
// Looking at the JTabbedPane sources, there is always one AccessibleSelection.
jobject selAccessible = getAxContextSelection(env, axContext, 0, fComponent);
if (selAccessible == NULL) return nil;
// Go through the tabs and find selAccessible
_numTabs = [tabs count];
JavaBaseAccessibility *aTab;
NSInteger i;
for (i = 0; i < _numTabs; i++) {
aTab = [(PlatformAxElement *)[tabs objectAtIndex:i] javaBase];
if ([aTab isAccessibleWithEnv:env forAccessible:selAccessible]) {
(*env)->DeleteLocalRef(env, selAccessible);
return [aTab platformAxElement];
}
}
(*env)->DeleteLocalRef(env, selAccessible);
return nil;
}
- (NSArray *)tabButtonsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored {
jobjectArray jtabsAndRoles = (jobjectArray)JNFCallStaticObjectMethod(env, jm_getChildrenAndRoles, fAccessible, fComponent, whichTabs, allowIgnored); // AWT_THREADING Safe (AWTRunLoop)
if(jtabsAndRoles == NULL) return nil;
jsize arrayLen = (*env)->GetArrayLength(env, jtabsAndRoles);
if (arrayLen == 0) {
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return nil;
}
NSMutableArray *tabs = [NSMutableArray arrayWithCapacity:(arrayLen/2)];
// all of the tabs have the same role, so we can just find out what that is here and use it for all the tabs
jobject jtabJavaRole = (*env)->GetObjectArrayElement(env, jtabsAndRoles, 1); // the array entries alternate between tab/role, starting with tab. so the first role is entry 1.
if (jtabJavaRole == NULL) {
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return nil;
}
jobject jkey = JNFGetObjectField(env, jtabJavaRole, sjf_key);
NSString *tabJavaRole = JNFJavaToNSString(env, jkey);
(*env)->DeleteLocalRef(env, jkey);
NSInteger i;
NSUInteger tabIndex = (whichTabs >= 0) ? whichTabs : 0; // if we're getting one particular child, make sure to set its index correctly
for(i = 0; i < arrayLen; i+=2) {
jobject jtab = (*env)->GetObjectArrayElement(env, jtabsAndRoles, i);
JavaBaseAccessibility *tab = [[[JavaTabButtonAccessibility alloc] initWithParent:self withEnv:env withAccessible:jtab withIndex:tabIndex withTabGroup:axContext withView:[self view] withJavaRole:tabJavaRole] autorelease];
(*env)->DeleteLocalRef(env, jtab);
[tabs addObject:[tab platformAxElement]];
tabIndex++;
}
(*env)->DeleteLocalRef(env, jtabsAndRoles);
return tabs;
}
- (NSArray *)contentsWithEnv:(JNIEnv *)env withTabGroupAxContext:(jobject)axContext withTabCode:(NSInteger)whichTabs allowIgnored:(BOOL)allowIgnored {
// Contents are the children of the selected tab.
PlatformAxElement *currentTab = [self currentTabWithEnv:env withAxContext:axContext];
if (currentTab == nil) return nil;
NSArray *contents = [JavaBaseAccessibility childrenOfParent:[currentTab javaBase] withEnv:env withChildrenCode:whichTabs allowIgnored:allowIgnored];
if ([contents count] <= 0) return nil;
return contents;
}
- (NSArray *)accessibleTabs {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
id tabs = [self tabButtonsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
(*env)->DeleteLocalRef(env, axContext);
return tabs;
}
- (NSArray *) accessibleContents {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
NSArray* cont = [self contentsWithEnv:env withTabGroupAxContext:axContext withTabCode:JAVA_AX_ALL_CHILDREN allowIgnored:NO];
(*env)->DeleteLocalRef(env, axContext);
return cont;
}
-(id) accessibleValue {
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
id val = [self currentTabWithEnv:env withAxContext:axContext];
(*env)->DeleteLocalRef(env, axContext);
return val;
}
- (NSInteger)numTabs {
return _numTabs;
}
@end
@implementation PlatformAxTabGroup
- (NSArray *)accessibilityTabs {
return [(JavaTabGroupAccessibility *)[self javaBase] accessibleTabs];
}
- (NSArray *)accessibilityContents {
return [(JavaTabGroupAccessibility *)[self javaBase] accessibleContents];
}
- (id)accessibilityValue {
return [(JavaTabGroupAccessibility *)[self javaBase] accessibleValue];
}
- (NSArray *)accessibilityChildren {
//children = AXTabs + AXContents
NSArray *tabs = [self accessibilityTabs];
NSArray *contents = [self accessibilityContents];
NSMutableArray *children = [NSMutableArray arrayWithCapacity:[tabs count] + [contents count]];
[children addObjectsFromArray:tabs];
[children addObjectsFromArray:contents];
return (NSArray *)children;
}
- (NSArray *)accessibilityArrayAttributeValues:(NSAccessibilityAttributeName)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount {
NSArray *result = nil;
if ( (maxCount == 1) && [attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
// Children codes for ALL, SELECTED, VISIBLE are <0. If the code is >=0, we treat it as an index to a single child
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [(JavaTabGroupAccessibility *)[self javaBase] axContextWithEnv:env];
//children = AXTabs + AXContents
NSArray *children = [(JavaTabGroupAccessibility *)[self javaBase] tabButtonsWithEnv:env
withTabGroupAxContext:axContext
withTabCode:index
allowIgnored:NO]; // first look at the tabs
if ([children count] > 0) {
result = children;
} else {
children= [(JavaTabGroupAccessibility *)[self javaBase] contentsWithEnv:env
withTabGroupAxContext:axContext
withTabCode:(index-[(JavaTabGroupAccessibility *)[self javaBase] numTabs])
allowIgnored:NO];
if ([children count] > 0) {
result = children;
}
}
(*env)->DeleteLocalRef(env, axContext);
} else {
result = [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
}
return result;
}
- (void)setAccessibilityValue:(id)accessibilityValue {
NSNumber *number = (NSNumber *)accessibilityValue;
if (![number boolValue]) return;
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axContext = [self axContextWithEnv:env];
setAxContextSelection(env, axContext, [[self javaBase] index], [[self javaBase] component]);
(*env)->DeleteLocalRef(env, axContext);
}
@end

View File

@@ -57,6 +57,7 @@ static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable
for (int i = 0; i < arrayLen; i++) {
[nsArraySelectidRowNumbers addObject:[NSNumber numberWithInt:indexsis[i]]];
}
(*env)->DeleteLocalRef(env, selectidRowNumbers);
return [NSArray<NSNumber *> arrayWithArray:nsArraySelectidRowNumbers];
}
@@ -76,18 +77,17 @@ static const char* ACCESSIBLE_JTABLE_NAME = "javax.swing.JTable$AccessibleJTable
for (int i = 0; i < arrayLen; i++) {
[nsArraySelectidColumnNumbers addObject:[NSNumber numberWithInt:indexsis[i]]];
}
(*env)->DeleteLocalRef(env, selectidColumnNumbers);
return [NSArray<NSNumber *> arrayWithArray:nsArraySelectidColumnNumbers];
}
- (int)accessibleRowAtIndex:(int)index {
printf("Пришёл индекс %d\n", index);
JNIEnv *env = [ThreadUtilities getJNIEnv];
JNFClassInfo clsInfo;
clsInfo.name = ACCESSIBLE_JTABLE_NAME;
clsInfo.cls = (*env)->GetObjectClass(env, [self axContextWithEnv:env]);
JNF_MEMBER_CACHE(jm_getAccessibleRowAtIndex, clsInfo, "getAccessibleRowAtIndex", "(I)I");
jint rowAtIndex = JNFCallIntMethod(env, [self axContextWithEnv:env], jm_getAccessibleRowAtIndex, (jint)index);
printf("Получен индекс %d\n", rowAtIndex);
return (int)rowAtIndex;
}

View File

@@ -1,10 +1,5 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
#ifndef JavaTableRowAccessibility_h
#define JavaTableRowAccessibility_h
#endif /* JavaTableRowAccessibility_h */
#import "JavaElementAccessibility.h"
@interface JavaTableRowAccessibility : JavaElementAccessibility

View File

@@ -1,63 +0,0 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#import "JavaComponentAccessibility.h"
#import <AppKit/NSAccessibility.h>
@interface JavaTextAccessibility : JavaComponentAccessibility {
}
// attributes
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env;
- (NSString *)accessibilityValueAttribute;
- (BOOL)accessibilityIsValueAttributeSettable;
- (void)accessibilitySetValueAttribute:(id)value;
- (NSString *)accessibilitySelectedTextAttribute;
- (BOOL)accessibilityIsSelectedTextAttributeSettable;
- (NSValue *)accessibilitySelectedTextRangeAttribute;
- (BOOL)accessibilityIsSelectedTextRangeAttributeSettable;
- (NSNumber *)accessibilityNumberOfCharactersAttribute;
- (BOOL)accessibilityIsNumberOfCharactersAttributeSettable;
- (NSValue *)accessibilityVisibleCharacterRangeAttribute;
- (BOOL)accessibilityIsVisibleCharacterRangeAttributeSettable;
- (NSValue *)accessibilityInsertionPointLineNumberAttribute;
- (BOOL)accessibilityIsInsertionPointLineNumberAttributeSettable;
- (void)accessibilitySetSelectedTextAttribute:(id)value;
- (NSValue *)accessibilitySelectedTextRangeAttribute;
- (NSValue *)accessibilityInsertionPointLineNumberAttribute;
- (BOOL)accessibilityIsInsertionPointLineNumberAttributeSettable;
// parameterized attributes
- (NSArray *)accessibilityParameterizedAttributeNames;
- (NSValue *)accessibilityBoundsForRangeAttributeForParameter:(id)parameter;
- (NSNumber *)accessibilityLineForIndexAttributeForParameter:(id)parameter;
- (NSValue *)accessibilityRangeForLineAttributeForParameter:(id)parameter;
- (NSString *)accessibilityStringForRangeAttributeForParameter:(id)parameter;
- (NSValue *)accessibilityRangeForPositionAttributeForParameter:(id)parameter;
- (NSValue *)accessibilityRangeForIndexAttributeForParameter:(id)parameter;
@end

View File

@@ -1,441 +0,0 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#import "JavaTextAccessibility.h"
#import "JavaAccessibilityAction.h"
#import "JavaAccessibilityUtilities.h"
#import "ThreadUtilities.h"
static JNF_CLASS_CACHE(sjc_CAccessibleText, "sun/lwawt/macosx/CAccessibleText");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleText, sjc_CAccessibility, "getAccessibleText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleEditableText, sjc_CAccessibleText, "getAccessibleEditableText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljavax/accessibility/AccessibleEditableText;");
static JNF_STATIC_MEMBER_CACHE(sjm_getAccessibleName, sjc_CAccessibility, "getAccessibleName", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
/*
* Converts an int array to an NSRange wrapped inside an NSValue
* takes [start, end] values and returns [start, end - start]
*/
NSValue *javaIntArrayToNSRangeValue(JNIEnv* env, jintArray array) {
jint *values = (*env)->GetIntArrayElements(env, array, 0);
if (values == NULL) {
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
NSLog(@"%s failed calling GetIntArrayElements", __FUNCTION__);
return nil;
};
NSValue *value = [NSValue valueWithRange:NSMakeRange(values[0], values[1] - values[0])];
(*env)->ReleaseIntArrayElements(env, array, values, 0);
return value;
}
@implementation JavaTextAccessibility
// based strongly upon NSTextViewAccessibility:accessibilityAttributeNames
- (NSArray *)initializeAttributeNamesWithEnv:(JNIEnv *)env
{
static NSArray *attributes = nil;
if (attributes == nil) {
//APPKIT_LOCK;
if (attributes == nil) {
NSMutableArray *temp = [[super initializeAttributeNamesWithEnv:env] mutableCopy];
//[temp removeObject:NSAccessibilityTitleAttribute]; // title may have been set in the superclass implementation - some static text reports from java that it has a name
[temp addObjectsFromArray:[NSArray arrayWithObjects:
NSAccessibilityValueAttribute,
NSAccessibilitySelectedTextAttribute,
NSAccessibilitySelectedTextRangeAttribute,
NSAccessibilityNumberOfCharactersAttribute,
NSAccessibilityVisibleCharacterRangeAttribute,
NSAccessibilityInsertionPointLineNumberAttribute,
// NSAccessibilitySharedTextUIElementsAttribute, // cmcnote: investigate what these two are for. currently unimplemented
// NSAccessibilitySharedCharacterRangeAttribute,
nil]];
attributes = [[NSArray alloc] initWithArray:temp];
[temp release];
}
//APPKIT_UNLOCK;
}
return attributes;
}
// copied from NSTextViewAccessibility.
- (NSArray *)accessibilityParameterizedAttributeNames
{
static NSArray *attributes = nil;
if (attributes == nil) {
//APPKIT_LOCK;
if (attributes == nil) {
attributes = [[NSArray alloc] initWithObjects:
NSAccessibilityLineForIndexParameterizedAttribute,
NSAccessibilityRangeForLineParameterizedAttribute,
NSAccessibilityStringForRangeParameterizedAttribute,
NSAccessibilityRangeForPositionParameterizedAttribute,
NSAccessibilityRangeForIndexParameterizedAttribute,
NSAccessibilityBoundsForRangeParameterizedAttribute,
//NSAccessibilityRTFForRangeParameterizedAttribute, // cmcnote: not sure when/how these three are used. Investigate. radr://3960026
//NSAccessibilityStyleRangeForIndexParameterizedAttribute,
//NSAccessibilityAttributedStringForRangeParameterizedAttribute,
nil];
}
//APPKIT_UNLOCK;
}
return attributes;
}
- (NSString *)accessibilityValueAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
if ([[self accessibilityRoleAttribute] isEqualToString:NSAccessibilityStaticTextRole]) {
// if it's static text, the AppKit AXValue is the java accessibleName
jobject axName = JNFCallStaticObjectMethod(env, sjm_getAccessibleName, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axName != NULL) {
NSString* str = JNFJavaToNSString(env, axName);
(*env)->DeleteLocalRef(env, axName);
return str;
}
// value is still nil if no accessibleName for static text. Below, try to get the accessibleText.
}
// cmcnote: inefficient to make three distinct JNI calls. Coalesce. radr://3951923
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return nil;
(*env)->DeleteLocalRef(env, axText);
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return nil;
static JNF_STATIC_MEMBER_CACHE(jm_getTextRange, sjc_CAccessibleText, "getTextRange", "(Ljavax/accessibility/AccessibleEditableText;IILjava/awt/Component;)Ljava/lang/String;");
jobject jrange = JNFCallStaticObjectMethod(env, jm_getTextRange, axEditableText, 0, getAxTextCharCount(env, axEditableText, fComponent), fComponent);
NSString *string = JNFJavaToNSString(env, jrange); // AWT_THREADING Safe (AWTRunLoop)
(*env)->DeleteLocalRef(env, jrange);
(*env)->DeleteLocalRef(env, axEditableText);
if (string == nil) string = @"";
return string;
}
- (BOOL)accessibilityIsValueAttributeSettable
{
// if text is enabled and editable, it's settable (according to NSCellTextAttributesAccessibility)
BOOL isEnabled = [(NSNumber *)[self accessibilityEnabledAttribute] boolValue];
if (!isEnabled) return NO;
JNIEnv* env = [ThreadUtilities getJNIEnv];
jobject axEditableText = JNFCallStaticObjectMethod(env, sjm_getAccessibleEditableText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axEditableText == NULL) return NO;
(*env)->DeleteLocalRef(env, axEditableText);
return YES;
}
- (void)accessibilitySetValueAttribute:(id)value
{
// cmcnote: should set the accessibleEditableText to the stringValue of value - AccessibleEditableText.setTextContents(String s)
#ifdef JAVA_AX_DEBUG
NSLog(@"Not yet implemented: %s\n", __FUNCTION__); // radr://3954018
#endif
}
// Currently selected text (NSString)
- (NSString *)accessibilitySelectedTextAttribute
{
JNIEnv* env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedText, sjc_CAccessibleText, "getSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)Ljava/lang/String;");
jobject axText = JNFCallStaticObjectMethod(env, jm_getSelectedText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axText == NULL) return @"";
NSString* str = JNFJavaToNSString(env, axText);
(*env)->DeleteLocalRef(env, axText);
return str;
}
- (BOOL)accessibilityIsSelectedTextAttributeSettable
{
return YES; //cmcnote: for AXTextField that's selectable, it's settable. Investigate further.
}
- (void)accessibilitySetSelectedTextAttribute:(id)value
{
#ifdef JAVA_AX_DEBUG_PARMS
if (![value isKindOfClass:[NSString class]]) {
JavaAccessibilityRaiseSetAttributeToIllegalTypeException(__FUNCTION__, self, NSAccessibilitySelectedTextAttribute, value);
return;
}
#endif
JNIEnv *env = [ThreadUtilities getJNIEnv];
jstring jstringValue = JNFNSToJavaString(env, (NSString *)value);
static JNF_STATIC_MEMBER_CACHE(jm_setSelectedText, sjc_CAccessibleText, "setSelectedText", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;Ljava/lang/String;)V");
JNFCallStaticVoidMethod(env, jm_setSelectedText, fAccessible, fComponent, jstringValue); // AWT_THREADING Safe (AWTRunLoop)
}
// Range of selected text (NSValue)
- (NSValue *)accessibilitySelectedTextRangeAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getSelectedTextRange, sjc_CAccessibleText, "getSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getSelectedTextRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env, axTextRange);
}
- (BOOL)accessibilityIsSelectedTextRangeAttributeSettable
{
return [(NSNumber *)[self accessibilityEnabledAttribute] boolValue]; // cmcnote: also may want to find out if isSelectable. Investigate.
}
- (void)accessibilitySetSelectedTextRangeAttribute:(id)value
{
#ifdef JAVA_AX_DEBUG_PARMS
if (!([value isKindOfClass:[NSValue class]] && strcmp([(NSValue *)value objCType], @encode(NSRange)) == 0)) {
JavaAccessibilityRaiseSetAttributeToIllegalTypeException(__FUNCTION__, self, NSAccessibilitySelectedTextRangeAttribute, value);
return;
}
#endif
NSRange range = [(NSValue *)value rangeValue];
jint startIndex = range.location;
jint endIndex = startIndex + range.length;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_setSelectedTextRange, sjc_CAccessibleText, "setSelectedTextRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)V");
JNFCallStaticVoidMethod(env, jm_setSelectedTextRange, fAccessible, fComponent, startIndex, endIndex); // AWT_THREADING Safe (AWTRunLoop)
}
- (NSNumber *)accessibilityNumberOfCharactersAttribute
{
// cmcnote: should coalesce these two calls - radr://3951923
// also, static text doesn't always have accessibleText. if axText is null, should get the charcount of the accessibleName instead
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject axText = JNFCallStaticObjectMethod(env, sjm_getAccessibleText, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
NSNumber* num = [NSNumber numberWithInt:getAxTextCharCount(env, axText, fComponent)];
(*env)->DeleteLocalRef(env, axText);
return num;
}
- (BOOL)accessibilityIsNumberOfCharactersAttributeSettable
{
return NO; // according to NSTextViewAccessibility.m and NSCellTextAttributesAccessibility.m
}
- (NSValue *)accessibilityVisibleCharacterRangeAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getVisibleCharacterRange, sjc_CAccessibleText, "getVisibleCharacterRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)[I");
jintArray axTextRange = JNFCallStaticObjectMethod(env, jm_getVisibleCharacterRange, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env, axTextRange);
}
- (BOOL)accessibilityIsVisibleCharacterRangeAttributeSettable
{
#ifdef JAVA_AX_DEBUG
NSLog(@"Not yet implemented: %s\n", __FUNCTION__);
#endif
return NO;
}
- (NSValue *)accessibilityInsertionPointLineNumberAttribute
{
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForInsertionPoint, sjc_CAccessibleText, "getLineNumberForInsertionPoint", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForInsertionPoint, fAccessible, fComponent); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return [NSNumber numberWithInt:row];
}
- (BOOL)accessibilityIsInsertionPointLineNumberAttributeSettable
{
#ifdef JAVA_AX_DEBUG
NSLog(@"Not yet implemented: %s\n", __FUNCTION__);
#endif
return NO;
}
// parameterized attributes
//
// Usage of accessibilityBoundsForRangeAttributeForParameter:
// ---
// called by VoiceOver when interacting with text via ctrl-option-shift-downArrow.
// Need to know bounding box for the character / word / line of interest in
// order to draw VoiceOver cursor
//
- (NSValue *)accessibilityBoundsForRangeAttributeForParameter:(id)parameter
{
#ifdef JAVA_AX_DEBUG_PARMS
if (!([parameter isKindOfClass:[NSValue class]] && strcmp([(NSValue *)parameter objCType], @encode(NSRange)) == 0)) {
JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityBoundsForRangeParameterizedAttribute, parameter);
return nil;
}
#endif
NSRange range = [(NSValue *)parameter rangeValue];
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getBoundsForRange, sjc_CAccessibleText, "getBoundsForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)[D");
jdoubleArray axBounds = (jdoubleArray)JNFCallStaticObjectMethod(env, jm_getBoundsForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (axBounds == NULL) return nil;
// We cheat because we know that the array is 4 elements long (x, y, width, height)
jdouble *values = (*env)->GetDoubleArrayElements(env, axBounds, 0);
if (values == NULL) {
// Note: Java will not be on the stack here so a java exception can't happen and no need to call ExceptionCheck.
NSLog(@"%s failed calling GetDoubleArrayElements", __FUNCTION__);
return nil;
};
NSRect bounds;
bounds.origin.x = values[0];
bounds.origin.y = [[[[self view] window] screen] frame].size.height - values[1] - values[3]; //values[1] is y-coord from top-left of screen. Flip. Account for the height (values[3]) when flipping
bounds.size.width = values[2];
bounds.size.height = values[3];
NSValue *result = [NSValue valueWithRect:bounds];
(*env)->ReleaseDoubleArrayElements(env, axBounds, values, 0);
return result;
}
- (NSNumber *)accessibilityLineForIndexAttributeForParameter:(id)parameter
{
NSNumber *line = (NSNumber *) parameter;
if (line == nil) return nil;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getLineNumberForIndex, sjc_CAccessibleText, "getLineNumberForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)I");
jint row = JNFCallStaticIntMethod(env, jm_getLineNumberForIndex, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop)
if (row < 0) return nil;
return [NSNumber numberWithInt:row];
}
- (NSValue *)accessibilityRangeForLineAttributeForParameter:(id)parameter
{
NSNumber *line = (NSNumber *) parameter;
if (line == nil) return nil;
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForLine, sjc_CAccessibleText, "getRangeForLine", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForLine, fAccessible, fComponent, [line intValue]); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env,axTextRange);
}
//
// Usage of accessibilityStringForRangeAttributeForParameter:
// ---
// called by VoiceOver when interacting with text via ctrl-option-shift-downArrow.
// VO needs to know the particular string its currently dealing with so it can
// speak the string
//
- (NSString *)accessibilityStringForRangeAttributeForParameter:(id)parameter
{
#ifdef JAVA_AX_DEBUG_PARMS
if (!([parameter isKindOfClass:[NSValue class]] && strcmp([(NSValue *)parameter objCType], @encode(NSRange)) == 0)) {
JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityBoundsForRangeParameterizedAttribute, parameter);
return nil;
}
#endif
NSRange range = [(NSValue *)parameter rangeValue];
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getStringForRange, sjc_CAccessibleText, "getStringForRange", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)Ljava/lang/String;");
jstring jstringForRange = (jstring)JNFCallStaticObjectMethod(env, jm_getStringForRange, fAccessible, fComponent, range.location, range.length); // AWT_THREADING Safe (AWTRunLoop)
if (jstringForRange == NULL) return @"";
NSString* str = JNFJavaToNSString(env, jstringForRange);
(*env)->DeleteLocalRef(env, jstringForRange);
return str;
}
//
// Usage of accessibilityRangeForPositionAttributeForParameter:
// ---
// cmcnote: I'm not sure when this is called / how it's used. Investigate.
// probably could be used in a special text-only accessibilityHitTest to
// find the index of the string under the mouse?
//
- (NSValue *)accessibilityRangeForPositionAttributeForParameter:(id)parameter
{
#ifdef JAVA_AX_DEBUG_PARMS
if (!([parameter isKindOfClass:[NSValue class]] && strcmp([(NSValue *)parameter objCType], @encode(NSPoint)) == 0)) {
JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityRangeForPositionParameterizedAttribute, parameter);
return nil;
}
#endif
NSPoint point = [(NSValue *)parameter pointValue]; // point is in screen coords
point.y = [[[[self view] window] screen] frame].size.height - point.y; // flip into java screen coords (0 is at upper-left corner of screen)
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getCharacterIndexAtPosition, sjc_CAccessibleText, "getCharacterIndexAtPosition", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;II)I");
jint charIndex = JNFCallStaticIntMethod(env, jm_getCharacterIndexAtPosition, fAccessible, fComponent, point.x, point.y); // AWT_THREADING Safe (AWTRunLoop)
if (charIndex == -1) return nil;
// AccessibleText.getIndexAtPoint returns -1 for an invalid point
NSRange range = NSMakeRange(charIndex, 1); //range's length is 1 - one-character range
return [NSValue valueWithRange:range];
}
//
// Usage of accessibilityRangeForIndexAttributeForParameter:
// ---
// cmcnote: I'm not sure when this is called / how it's used. Investigate.
// AppKit version calls: [string rangeOfComposedCharacterSequenceAtIndex:index]
// We call: CAccessibility.getRangeForIndex, which calls AccessibleText.getAtIndex(AccessibleText.WORD, index)
// to determine the word closest to the given index. Then we find the length/location of this string.
//
- (NSValue *)accessibilityRangeForIndexAttributeForParameter:(id)parameter
{
#ifdef JAVA_AX_DEBUG_PARMS
if (![parameter isKindOfClass:[NSNumber class]]) {
JavaAccessibilityRaiseIllegalParameterTypeException(__FUNCTION__, self, NSAccessibilityRangeForIndexParameterizedAttribute, parameter);
return nil;
}
#endif
NSUInteger index = [(NSNumber *)parameter unsignedIntegerValue];
JNIEnv *env = [ThreadUtilities getJNIEnv];
static JNF_STATIC_MEMBER_CACHE(jm_getRangeForIndex, sjc_CAccessibleText, "getRangeForIndex", "(Ljavax/accessibility/Accessible;Ljava/awt/Component;I)[I");
jintArray axTextRange = (jintArray)JNFCallStaticObjectMethod(env, jm_getRangeForIndex, fAccessible, fComponent, index); // AWT_THREADING Safe (AWTRunLoop)
if (axTextRange == NULL) return nil;
return javaIntArrayToNSRangeValue(env, axTextRange);
}
/*
* - (NSDictionary *)getActions:(JNIEnv *)env { ... }
*
* In the future, possibly add support: Editable text has AXShowMenu.
* Textfields have AXConfirm.
*
* Note: JLabels (static text) in JLists have a press/click selection action
* which is currently handled in superclass JavaComponentAccessibility.
* If function is added here be sure to use [super getActions:env] for JLabels.
*/
@end

View File

@@ -35,6 +35,8 @@
JRSFontRenderingStyle fStyle;
jint fAAStyle;
jint fFmHint;
jint fSubpixelResolutionX;
jint fSubpixelResolutionY;
CGAffineTransform fTx;
CGAffineTransform fDevTx;
@@ -42,6 +44,13 @@
CGAffineTransform fFontTx;
}
+ (AWTStrike *) awtStrikeForFont:(AWTFont *)awtFont tx:(CGAffineTransform)tx invDevTx:(CGAffineTransform)invDevTx style:(JRSFontRenderingStyle)style aaStyle:(jint)aaStyle fmHint:(jint)fmHint;
+ (AWTStrike *) awtStrikeForFont:(AWTFont *)awtFont
tx:(CGAffineTransform)tx
invDevTx:(CGAffineTransform)invDevTx
style:(JRSFontRenderingStyle)style
aaStyle:(jint)aaStyle
fmHint:(jint)fmHint
subpixelResolutionX:(jint)subpixelResolutionX
subpixelResolutionY:(jint)subpixelResolutionY;
@end

View File

@@ -42,7 +42,9 @@ static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
invDevTx:(CGAffineTransform)invDevTx
style:(JRSFontRenderingStyle)style
aaStyle:(jint)aaStyle
fmHint:(jint)fmHint {
fmHint:(jint)fmHint
subpixelResolutionX:(jint)subpixelResolutionX
subpixelResolutionY:(jint)subpixelResolutionY {
self = [super init];
if (self) {
@@ -50,6 +52,8 @@ static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
fStyle = style;
fAAStyle = aaStyle;
fFmHint = fmHint;
fSubpixelResolutionX = subpixelResolutionX;
fSubpixelResolutionY = subpixelResolutionY;
fTx = tx; // composited glyph and device transform
@@ -80,13 +84,17 @@ static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
invDevTx:(CGAffineTransform)invDevTx
style:(JRSFontRenderingStyle)style
aaStyle:(jint)aaStyle
fmHint:(jint)fmHint {
fmHint:(jint)fmHint
subpixelResolutionX:(jint)subpixelResolutionX
subpixelResolutionY:(jint)subpixelResolutionY {
return [[[AWTStrike alloc] initWithFont:awtFont
tx:tx invDevTx:invDevTx
style:style
aaStyle:aaStyle
fmHint:fmHint] autorelease];
fmHint:fmHint
subpixelResolutionX:subpixelResolutionX
subpixelResolutionY:subpixelResolutionY] autorelease];
}
@end
@@ -405,7 +413,8 @@ JNF_COCOA_EXIT(env);
* Signature: (J[D[DII)J
*/
JNIEXPORT jlong JNICALL Java_sun_font_CStrike_createNativeStrikePtr
(JNIEnv *env, jclass clazz, jlong nativeFontPtr, jdoubleArray glyphTxArray, jdoubleArray invDevTxArray, jint aaStyle, jint fmHint)
(JNIEnv *env, jclass clazz, jlong nativeFontPtr, jdoubleArray glyphTxArray, jdoubleArray invDevTxArray,
jint aaStyle, jint fmHint, jint subpixelResolutionX, jint subpixelResolutionY)
{
AWTStrike *awtStrike = nil;
JNF_COCOA_ENTER(env);
@@ -416,7 +425,8 @@ JNF_COCOA_ENTER(env);
CGAffineTransform glyphTx = GetTxFromDoubles(env, glyphTxArray);
CGAffineTransform invDevTx = GetTxFromDoubles(env, invDevTxArray);
awtStrike = [AWTStrike awtStrikeForFont:awtFont tx:glyphTx invDevTx:invDevTx style:style aaStyle:aaStyle fmHint:fmHint]; // autoreleased
awtStrike = [AWTStrike awtStrikeForFont:awtFont tx:glyphTx invDevTx:invDevTx style:style
aaStyle:aaStyle fmHint:fmHint subpixelResolutionX:subpixelResolutionX subpixelResolutionY:subpixelResolutionY]; // autoreleased
if (awtStrike)
{

View File

@@ -285,6 +285,64 @@ CGGI_ConvertBWPixelToByteGray(UInt32 p)
return 0xFF - (((p >> 24 & 0xFF) + (p >> 16 & 0xFF) + (p >> 8 & 0xFF)) / 3);
}
static void
CGGI_CopySubpixelImageFromCanvasToAlphaInfo(const UInt32* srcImage, int srcRowWidth,
UInt8* dstImage,
int dstWidth, int dstHeight,
int subpixelResolutionX,
int subpixelResolutionY,
short *tempBuffer)
{
int srcWidth = dstWidth * subpixelResolutionX;
int srcHeight = dstHeight * subpixelResolutionY;
int imageSize = dstWidth * dstHeight;
int xGlyph, yGlyph, x, y;
// For each subpixel offset by x axis
for (xGlyph = 0; xGlyph < subpixelResolutionX; xGlyph++) {
// Sum values by x axis and store into temporary buffer
for (y = 0; y < srcHeight; y++) {
for (x = 0; x < dstWidth; x++) {
int value = 0;
int xFrom = x * subpixelResolutionX - xGlyph,
xTo = xFrom + subpixelResolutionX;
if (xFrom < 0) xFrom = 0;
if (xTo > srcWidth) xTo = srcWidth;
int i;
for (i = xFrom; i < xTo; i++) {
value += CGGI_ConvertBWPixelToByteGray(
srcImage[y * srcRowWidth + i]);
}
tempBuffer[y * dstWidth + x] = (short) value;
}
}
// For each subpixel offset by y axis
for (yGlyph = 0; yGlyph < subpixelResolutionY; yGlyph++) {
UInt8 *dst = dstImage +
imageSize * (xGlyph + yGlyph * subpixelResolutionX);
// Sum values by y axis and store average into destination image
for (y = 0; y < dstHeight; y++) {
for (x = 0; x < dstWidth; x++) {
int value = 0;
int yFrom = y * subpixelResolutionY - yGlyph,
yTo = yFrom + subpixelResolutionY;
if (yFrom < 0) yFrom = 0;
if (yTo > srcHeight) yTo = srcHeight;
int j;
for (j = yFrom; j < yTo; j++) {
value += tempBuffer[j * dstWidth + x];
}
dst[y * dstWidth + x] =
value / subpixelResolutionX / subpixelResolutionY;
}
}
}
}
}
/* Size (in pixels) of stack-allocated temporary buffer for glyph downscaling.
* If glyph is too big and requires more memory, it will use malloc. */
#define SUBPIXEL_DOWNSCALE_STATIC_BUFFER_SIZE 2048
static void
CGGI_CopyImageFromCanvasToAlphaInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
{
@@ -296,16 +354,35 @@ CGGI_CopyImageFromCanvasToAlphaInfo(CGGI_GlyphCanvas *canvas, GlyphInfo *info)
size_t height = info->height;
size_t y;
// fill empty glyph image with black-on-white glyph
for (y = 0; y < height; y++) {
size_t destRow = y * destRowWidth;
size_t srcRow = y * srcRowWidth;
size_t x;
for (x = 0; x < destRowWidth; x++) {
UInt32 p = src[srcRow + x];
dest[destRow + x] = CGGI_ConvertBWPixelToByteGray(p);
if (info->subpixelResolutionX > 1 || info->subpixelResolutionY > 1) {
int bufferSize = destRowWidth * height * info->subpixelResolutionY;
if (bufferSize <= SUBPIXEL_DOWNSCALE_STATIC_BUFFER_SIZE) {
short staticBuffer[bufferSize];
CGGI_CopySubpixelImageFromCanvasToAlphaInfo(
src, srcRowWidth,
dest, destRowWidth, height,
info->subpixelResolutionX, info->subpixelResolutionY,
staticBuffer);
} else {
short *buffer = malloc(sizeof(short) * bufferSize);
CGGI_CopySubpixelImageFromCanvasToAlphaInfo(
src, srcRowWidth,
dest, destRowWidth, height,
info->subpixelResolutionX, info->subpixelResolutionY,
buffer);
free(buffer);
}
} else {
size_t y;
// fill empty glyph image with black-on-white glyph
for (y = 0; y < height; y++) {
size_t destRow = y * destRowWidth;
size_t srcRow = y * srcRowWidth;
size_t x;
for (x = 0; x < destRowWidth; x++) {
UInt32 p = src[srcRow + x];
dest[destRow + x] = CGGI_ConvertBWPixelToByteGray(p);
}
}
}
}
@@ -353,8 +430,10 @@ typedef struct CGGI_GlyphInfoDescriptor {
} CGGI_GlyphInfoDescriptor;
typedef struct CGGI_RenderingMode {
CGGI_GlyphInfoDescriptor *glyphDescriptor;
CGGI_GlyphInfoDescriptor *mainFontDescriptor;
JRSFontRenderingStyle cgFontMode;
bool lcdRendering;
bool subpixelResolution;
} CGGI_RenderingMode;
static CGGI_GlyphInfoDescriptor grey =
@@ -379,7 +458,7 @@ static inline CGGI_GlyphInfoDescriptor*
CGGI_GetGlyphInfoDescriptor(const CGGI_RenderingMode *mode, CGFontRef font)
{
bool isFixedColor = CGGI_IsColorFont(font);
return isFixedColor ? &argb : mode->glyphDescriptor;
return isFixedColor ? &argb : mode->mainFontDescriptor;
}
static inline CGGI_RenderingMode
@@ -389,16 +468,26 @@ CGGI_GetRenderingMode(const AWTStrike *strike)
mode.cgFontMode = strike->fStyle;
NSException *e = nil;
#ifdef USE_IMAGE_ALIGNED_MEMORY
mode.subpixelResolution = false;
#else
mode.subpixelResolution = strike->fAAStyle == sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_ON &&
strike->fFmHint == sun_awt_SunHints_INTVAL_FRACTIONALMETRICS_ON &&
(strike->fSubpixelResolutionX > 1 || strike->fSubpixelResolutionY > 1);
#endif
switch (strike->fAAStyle) {
case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_OFF:
case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_ON:
mode.glyphDescriptor = &grey;
mode.lcdRendering = false;
mode.mainFontDescriptor = &grey;
break;
case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_HRGB:
case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_HBGR:
case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_VRGB:
case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_LCD_VBGR:
mode.glyphDescriptor = &rgb;
mode.lcdRendering = true;
mode.mainFontDescriptor = &rgb;
break;
case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_GASP:
case sun_awt_SunHints_INTVAL_TEXT_ANTIALIAS_DEFAULT:
@@ -412,6 +501,10 @@ CGGI_GetRenderingMode(const AWTStrike *strike)
userInfo:nil];
@throw e;
}
if (CGGI_IsColorFont(strike->fAWTFont->fNativeCGFont)) {
mode.mainFontDescriptor = &argb;
mode.subpixelResolution = false;
}
return mode;
}
@@ -444,7 +537,7 @@ CGGI_InitCanvas(CGGI_GlyphCanvas *canvas,
}
uint32_t bmpInfo = kCGImageAlphaPremultipliedFirst;
if (mode->glyphDescriptor == &rgb) {
if (mode->lcdRendering) {
bmpInfo |= kCGBitmapByteOrder32Host;
}
@@ -522,8 +615,8 @@ CGGI_ClearCanvas(CGGI_GlyphCanvas *canvas, GlyphInfo *info, bool transparent)
{
vImage_Buffer canvasRectToClear;
canvasRectToClear.data = canvas->image->data;
canvasRectToClear.height = info->height;
canvasRectToClear.width = info->width;
canvasRectToClear.height = info->height * info->subpixelResolutionY;
canvasRectToClear.width = info->width * info->subpixelResolutionX;
// use the row stride of the canvas, not the info
canvasRectToClear.rowBytes = canvas->image->rowBytes;
@@ -561,7 +654,8 @@ static inline CGSize CGGI_ScaleAdvance(CGSize advance, const AWTStrike *strike)
static inline GlyphInfo *
CGGI_CreateNewGlyphInfoFrom(CGSize advance, CGRect bbox,
const AWTStrike *strike,
const CGGI_GlyphInfoDescriptor *glyphDescriptor)
const CGGI_GlyphInfoDescriptor *glyphDescriptor,
bool subpixelResolution)
{
size_t pixelSize = glyphDescriptor->pixelSize;
@@ -573,8 +667,23 @@ CGGI_CreateNewGlyphInfoFrom(CGSize advance, CGRect bbox,
bbox.origin.x -= CGGI_GLYPH_BBOX_PADDING;
bbox.origin.y -= CGGI_GLYPH_BBOX_PADDING;
vImagePixelCount width = ceilf(bbox.size.width);
vImagePixelCount height = ceilf(bbox.size.height);
int subpixelResX = 1;
int subpixelResY = 1;
int topLeftX, topLeftY;
vImagePixelCount width, height;
if (subpixelResolution) {
subpixelResX = strike->fSubpixelResolutionX;
subpixelResY = strike->fSubpixelResolutionY;
topLeftX = floorf(bbox.origin.x / (float) subpixelResX);
topLeftY = floorf(bbox.origin.y / (float) subpixelResY);
width = ceilf((bbox.origin.x + bbox.size.width) / (float) subpixelResX) - topLeftX;
height = ceilf((bbox.origin.y + bbox.size.height) / (float) subpixelResY) - topLeftY;
} else {
topLeftX = round(bbox.origin.x);
topLeftY = round(bbox.origin.y);
width = ceilf(bbox.size.width);
height = ceilf(bbox.size.height);
}
// if the glyph is larger than 1MB, don't even try...
// the GlyphVector path should have taken over by now
@@ -595,17 +704,20 @@ CGGI_CreateNewGlyphInfoFrom(CGSize advance, CGRect bbox,
void *image = (void *)malloc(imageBytes + extraPixelStorage);
#else
// create a GlyphInfo struct fused to the image it points to
GlyphInfo *glyphInfo = (GlyphInfo *)malloc(sizeof(GlyphInfo) + imageBytes + extraPixelStorage);
GlyphInfo *glyphInfo = (GlyphInfo *)malloc(sizeof(GlyphInfo) +
(imageBytes + extraPixelStorage) * subpixelResX * subpixelResY);
#endif
glyphInfo->advanceX = advance.width;
glyphInfo->advanceY = advance.height;
glyphInfo->topLeftX = round(bbox.origin.x);
glyphInfo->topLeftY = round(bbox.origin.y);
glyphInfo->topLeftX = topLeftX;
glyphInfo->topLeftY = topLeftY;
glyphInfo->width = width;
glyphInfo->height = height;
glyphInfo->rowBytes = width * pixelSize;
glyphInfo->cellInfo = NULL;
glyphInfo->subpixelResolutionX = subpixelResX;
glyphInfo->subpixelResolutionY = subpixelResY;
#ifdef USE_IMAGE_ALIGNED_MEMORY
glyphInfo->image = image;
@@ -622,6 +734,19 @@ CGGI_CreateNewGlyphInfoFrom(CGSize advance, CGRect bbox,
#pragma mark --- Glyph Striking onto Canvas ---
static inline void CGGI_ScaleTXForSubpixelResolution(CGAffineTransform *tx,
const AWTStrike *strike,
bool subpixelResolution) {
if (subpixelResolution) {
float subResX = (float) strike->fSubpixelResolutionX;
float subResY = (float) strike->fSubpixelResolutionY;
tx->a *= subResX;
tx->b *= subResY;
tx->c *= subResX;
tx->d *= subResY;
}
}
/*
* Clears the canvas, strikes the glyph with CoreGraphics, and then
* copies the struck pixels into the GlyphInfo image.
@@ -647,12 +772,13 @@ CGGI_CreateImageForGlyph
CGGI_ClearCanvas(canvas, info, glyphDescriptor == &argb);
// strike the glyph in the upper right corner
CGFloat x = -info->topLeftX;
CGFloat y = canvas->image->height + info->topLeftY;
CGFloat x = -info->topLeftX * (float) info->subpixelResolutionX;
CGFloat y = canvas->image->height + info->topLeftY * (float) info->subpixelResolutionY;
if (isCatalinaOrAbove || glyphDescriptor == &argb) {
CGAffineTransform matrix = CGContextGetTextMatrix(canvas->context);
CGFloat fontSize = sqrt(fabs(matrix.a * matrix.d - matrix.b * matrix.c));
CGFloat fontSize = sqrt(fabs(matrix.a * matrix.d - matrix.b * matrix.c) /
(float) info->subpixelResolutionX / (float) info->subpixelResolutionY);
CTFontRef font = CTFontCreateWithGraphicsFont(cgFont, fontSize, NULL, NULL);
CGFloat normFactor = 1.0 / fontSize;
@@ -697,8 +823,10 @@ CGGI_CreateImageForUnicode
const CGGI_RenderingMode *mode, const UnicodeScalarValue uniChar,
const bool isCatalinaOrAbove)
{
// save the state of the world
// save the graphics state
CGContextSaveGState(canvas->context);
// text matrix is not considered part of graphics state
CGAffineTransform originalTx = CGContextGetTextMatrix(canvas->context);
// get the glyph, measure it using CG
CGGlyph glyph;
@@ -715,26 +843,32 @@ CGGI_CreateImageForUnicode
fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, &glyph, 1);
}
CGAffineTransform tx = strike->fTx;
JRSFontRenderingStyle style = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);
const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
CGGI_GlyphInfoDescriptor *glyphDescriptor = CGGI_GetGlyphInfoDescriptor(mode, cgFallback);
bool subpixelResolution = mode->subpixelResolution && glyphDescriptor == &grey;
CGAffineTransform tx = strike->fTx;
CGGI_ScaleTXForSubpixelResolution(&tx, strike, subpixelResolution);
CGRect bbox;
JRSFontGetBoundingBoxesForGlyphsAndStyle(fallback, &tx, style, &glyph, 1, &bbox);
CGSize advance;
CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &advance, 1);
const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
CGGI_GlyphInfoDescriptor *glyphDescriptor = CGGI_GetGlyphInfoDescriptor(mode, cgFallback);
// create the Sun2D GlyphInfo we are going to strike into
GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, glyphDescriptor);
GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, glyphDescriptor, subpixelResolution);
// fix the context size, just in case the substituted character is unexpectedly large
CGGI_SizeCanvas(canvas, info->width, info->height, mode);
CGGI_SizeCanvas(canvas, info->width * info->subpixelResolutionX, info->height * info->subpixelResolutionY, mode);
// align the transform for the real CoreText strike
CGContextSetTextMatrix(canvas->context, strike->fAltTx);
CGAffineTransform altTx = strike->fAltTx;
CGGI_ScaleTXForSubpixelResolution(&altTx, strike, subpixelResolution);
CGContextSetTextMatrix(canvas->context, altTx);
CGContextSetFont(canvas->context, cgFallback);
CFRelease(cgFallback);
@@ -742,8 +876,9 @@ CGGI_CreateImageForUnicode
// clean the canvas - align, strike, and copy the glyph from the canvas into the info
CGGI_CreateImageForGlyph(cgFallback, canvas, glyph, info, glyphDescriptor, strike, isCatalinaOrAbove);
// restore the state of the world
// restore graphics state
CGContextRestoreGState(canvas->context);
CGContextSetTextMatrix(canvas->context, originalTx);
CFRelease(fallback);
#ifdef CGGI_DEBUG
@@ -778,20 +913,20 @@ CGGI_FillImagesForGlyphsWithSizedCanvas(CGGI_GlyphCanvas *canvas,
const CGGlyph glyphs[],
const CFIndex len)
{
CGContextSetTextMatrix(canvas->context, strike->fAltTx);
CGAffineTransform tx = strike->fAltTx;
CGGI_ScaleTXForSubpixelResolution(&tx, strike, mode->subpixelResolution);
CGContextSetTextMatrix(canvas->context, tx);
CGContextSetFont(canvas->context, strike->fAWTFont->fNativeCGFont);
JRSFontSetRenderingStyleOnContext(canvas->context, strike->fStyle);
CGGI_GlyphInfoDescriptor* mainFontDescriptor = CGGI_GetGlyphInfoDescriptor(mode, strike->fAWTFont->fNativeCGFont);
const bool isMojaveOrAbove = IS_OSX_GT10_13;
CFIndex i;
for (i = 0; i < len; i++) {
GlyphInfo *info = (GlyphInfo *)jlong_to_ptr(glyphInfos[i]);
if (info != NULL) {
CGGI_CreateImageForGlyph(strike->fAWTFont->fNativeCGFont,
canvas, glyphs[i], info, mainFontDescriptor, strike, isMojaveOrAbove);
canvas, glyphs[i], info, mode->mainFontDescriptor, strike, isMojaveOrAbove);
} else {
info = CGGI_CreateImageForUnicode(canvas, strike, mode, uniChars[i], isMojaveOrAbove);
glyphInfos[i] = ptr_to_jlong(info);
@@ -850,7 +985,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
NSMutableDictionary *threadDict =
[[NSThread currentThread] threadDictionary];
NSString* theKey = (mode->glyphDescriptor == &rgb) ?
NSString* theKey = mode->lcdRendering ?
threadLocalLCDCanvasKey : threadLocalAACanvasKey;
CGGI_GlyphCanvas *canvas = [threadDict objectForKey:theKey];
@@ -882,6 +1017,7 @@ CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
{
AWTFont *font = strike->fAWTFont;
CGAffineTransform tx = strike->fTx;
CGGI_ScaleTXForSubpixelResolution(&tx, strike, mode->subpixelResolution);
JRSFontRenderingStyle bboxCGMode = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);
JRSFontGetBoundingBoxesForGlyphsAndStyle((CTFontRef)font->fFont, &tx, bboxCGMode, glyphs, len, bboxes);
@@ -890,8 +1026,6 @@ CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
size_t maxWidth = 1;
size_t maxHeight = 1;
CGGI_GlyphInfoDescriptor* mainFontDescriptor = CGGI_GetGlyphInfoDescriptor(mode, strike->fAWTFont->fNativeCGFont);
CFIndex i;
for (i = 0; i < len; i++)
{
@@ -904,10 +1038,15 @@ CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
CGSize advance = advances[i];
CGRect bbox = bboxes[i];
GlyphInfo *glyphInfo = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, mainFontDescriptor);
GlyphInfo *glyphInfo = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike,
mode->mainFontDescriptor,
mode->subpixelResolution);
if (maxWidth < glyphInfo->width) maxWidth = glyphInfo->width;
if (maxHeight < glyphInfo->height) maxHeight = glyphInfo->height;
int w = glyphInfo->width * glyphInfo->subpixelResolutionX;
int h = glyphInfo->height * glyphInfo->subpixelResolutionY;
if (maxWidth < w) maxWidth = w;
if (maxHeight < h) maxHeight = h;
glyphInfos[i] = ptr_to_jlong(glyphInfo);
}

Some files were not shown because too many files have changed in this diff Show More