diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index a494de1..853b2b5 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -31,10 +31,14 @@ jobs:
java-version: '25'
distribution: 'corretto'
- uses: gradle/actions/setup-gradle@v4
- - run: ./gradlew jpackage
+ # See https://docs.gradle.org/current/userguide/logging.html#sec:choosing_a_log_level for the log levels
+ # We opted for "-i", because it outputs the commands used to build the application image
+ - run: ./gradlew -i jpackage
+ - run: ls -la /Users/runner/work/javafxreproducer/javafxreproducer/build/tmp/jpackage/macos-14/app-content/Resources
+ if: ${{ always() && runner.os == 'macOS' }}
- name: Upload a Build Artifact
uses: actions/upload-artifact@v4
with:
name: javafxreproducer-${{ matrix.os }}
- path: build/distributions
+ path: build/packages
compression-level: 0
diff --git a/build.gradle.kts b/build.gradle.kts
index 751d3ce..88e612b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -108,4 +108,24 @@ javaModulePackaging {
architecture = MachineArchitecture.X86_64
packageTypes = listOf("app-image", "msi")
}
+
+ targetsWithOs("macos") {
+ options.addAll(
+ // "--icon", "$projectDir/src/main/resources/icons/jabref.icns",
+ "--mac-package-identifier", "JabRef",
+ "--mac-package-name", "JabRef",
+ "--file-associations", "$projectDir/buildres/macos/bibtexAssociations.properties",
+ )
+ if (providers.environmentVariable("OSXCERT").orNull?.isNotBlank() ?: false) {
+ options.addAll(
+ "--mac-sign",
+ "--mac-signing-key-user-name", "JabRef e.V. (6792V39SK3)",
+ "--mac-package-signing-prefix", "org.jabref",
+ )
+ }
+ targetResources.from(layout.projectDirectory.dir("buildres/macos").asFileTree.matching {
+ include("Resources/**")
+ })
+ }
+
}
diff --git a/buildres/macos/Info-lite.plist.template b/buildres/macos/Info-lite.plist.template
new file mode 100644
index 0000000..509eb84
--- /dev/null
+++ b/buildres/macos/Info-lite.plist.template
@@ -0,0 +1,39 @@
+
+
+
+
+ LSMinimumSystemVersion
+ 10.9
+ CFBundleDevelopmentRegion
+ English
+ CFBundleAllowMixedLocalizations
+
+ CFBundleExecutable
+ DEPLOY_LAUNCHER_NAME
+ CFBundleIconFile
+ DEPLOY_ICON_FILE
+ CFBundleIdentifier
+ DEPLOY_BUNDLE_IDENTIFIER
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ DEPLOY_BUNDLE_NAME
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ DEPLOY_BUNDLE_SHORT_VERSION
+ CFBundleSignature
+ ????
+
+ LSApplicationCategoryType
+ Unknown
+ CFBundleVersion
+ DEPLOY_BUNDLE_CFBUNDLE_VERSION
+ NSHumanReadableCopyright
+ DEPLOY_BUNDLE_COPYRIGHTDEPLOY_FILE_ASSOCIATIONS
+ NSHighResolutionCapable
+ true
+ NSSupportsAutomaticGraphicsSwitching
+
+
+
diff --git a/buildres/macos/Info.plist b/buildres/macos/Info.plist
new file mode 100644
index 0000000..509eb84
--- /dev/null
+++ b/buildres/macos/Info.plist
@@ -0,0 +1,39 @@
+
+
+
+
+ LSMinimumSystemVersion
+ 10.9
+ CFBundleDevelopmentRegion
+ English
+ CFBundleAllowMixedLocalizations
+
+ CFBundleExecutable
+ DEPLOY_LAUNCHER_NAME
+ CFBundleIconFile
+ DEPLOY_ICON_FILE
+ CFBundleIdentifier
+ DEPLOY_BUNDLE_IDENTIFIER
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ DEPLOY_BUNDLE_NAME
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ DEPLOY_BUNDLE_SHORT_VERSION
+ CFBundleSignature
+ ????
+
+ LSApplicationCategoryType
+ Unknown
+ CFBundleVersion
+ DEPLOY_BUNDLE_CFBUNDLE_VERSION
+ NSHumanReadableCopyright
+ DEPLOY_BUNDLE_COPYRIGHTDEPLOY_FILE_ASSOCIATIONS
+ NSHighResolutionCapable
+ true
+ NSSupportsAutomaticGraphicsSwitching
+
+
+
diff --git a/buildres/macos/Info.plist.template b/buildres/macos/Info.plist.template
new file mode 100644
index 0000000..509eb84
--- /dev/null
+++ b/buildres/macos/Info.plist.template
@@ -0,0 +1,39 @@
+
+
+
+
+ LSMinimumSystemVersion
+ 10.9
+ CFBundleDevelopmentRegion
+ English
+ CFBundleAllowMixedLocalizations
+
+ CFBundleExecutable
+ DEPLOY_LAUNCHER_NAME
+ CFBundleIconFile
+ DEPLOY_ICON_FILE
+ CFBundleIdentifier
+ DEPLOY_BUNDLE_IDENTIFIER
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ DEPLOY_BUNDLE_NAME
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ DEPLOY_BUNDLE_SHORT_VERSION
+ CFBundleSignature
+ ????
+
+ LSApplicationCategoryType
+ Unknown
+ CFBundleVersion
+ DEPLOY_BUNDLE_CFBUNDLE_VERSION
+ NSHumanReadableCopyright
+ DEPLOY_BUNDLE_COPYRIGHTDEPLOY_FILE_ASSOCIATIONS
+ NSHighResolutionCapable
+ true
+ NSSupportsAutomaticGraphicsSwitching
+
+
+
diff --git a/buildres/macos/JabRef-background-darkAqua.png b/buildres/macos/JabRef-background-darkAqua.png
new file mode 100644
index 0000000..0612c82
Binary files /dev/null and b/buildres/macos/JabRef-background-darkAqua.png differ
diff --git a/buildres/macos/JabRef-background.png b/buildres/macos/JabRef-background.png
new file mode 100644
index 0000000..0612c82
Binary files /dev/null and b/buildres/macos/JabRef-background.png differ
diff --git a/buildres/macos/JabRef-background.tiff b/buildres/macos/JabRef-background.tiff
new file mode 100644
index 0000000..62782b1
Binary files /dev/null and b/buildres/macos/JabRef-background.tiff differ
diff --git a/buildres/macos/JabRef-dmg-setup.scpt b/buildres/macos/JabRef-dmg-setup.scpt
new file mode 100644
index 0000000..1ed57f9
--- /dev/null
+++ b/buildres/macos/JabRef-dmg-setup.scpt
@@ -0,0 +1,44 @@
+tell application "Finder"
+ set theDisk to a reference to (disks whose URL = "DEPLOY_VOLUME_URL")
+ open theDisk
+
+ set theWindow to a reference to (container window of disks whose URL = "DEPLOY_VOLUME_URL")
+
+ set current view of theWindow to icon view
+ set toolbar visible of theWindow to false
+ set statusbar visible of theWindow to false
+
+ -- size of window should fit the size of background
+ set the bounds of theWindow to {346, 100, 920, 500}
+
+ set theViewOptions to a reference to the icon view options of theWindow
+ set arrangement of theViewOptions to not arranged
+ set icon size of theViewOptions to 128
+ set background picture of theViewOptions to POSIX file "DEPLOY_BG_FILE"
+
+ -- Create alias for install location
+ make new alias file at POSIX file "DEPLOY_VOLUME_PATH" to POSIX file "DEPLOY_INSTALL_LOCATION" with properties {name:"DEPLOY_INSTALL_LOCATION_DISPLAY_NAME"}
+
+ set allTheFiles to the name of every item of theWindow
+ set xpos to 120
+ repeat with theFile in allTheFiles
+ set theFilePath to POSIX path of theFile
+ set appFilePath to POSIX path of "/DEPLOY_TARGET"
+ if theFilePath ends with "DEPLOY_INSTALL_LOCATION_DISPLAY_NAME" then
+ -- Position install location application
+ set position of item theFile of theWindow to {440, 170}
+ else if theFilePath ends with appFilePath then
+ -- Position application or runtime
+ set position of item theFile of theWindow to {140, 170}
+ else
+ -- Position all other items in a second row.
+ set position of item theFile of theWindow to {xpos, 400}
+ set xpos to xpos + 150
+ end if
+ end repeat
+
+
+ update theDisk without registering applications
+ delay 5
+ close (get window of theDisk)
+end tell
diff --git a/buildres/macos/Jabref-volume.icns b/buildres/macos/Jabref-volume.icns
new file mode 100644
index 0000000..e231e8d
Binary files /dev/null and b/buildres/macos/Jabref-volume.icns differ
diff --git a/buildres/macos/README.md b/buildres/macos/README.md
new file mode 100644
index 0000000..495b574
--- /dev/null
+++ b/buildres/macos/README.md
@@ -0,0 +1,12 @@
+# Mac Resources
+
+## Modifying DMG Setup scpt
+
+Rename `JabRef-dmg-setup.scpt script` to `JabRef-dmg-setup.applescript`.
+Only modify the `JabRef-dmg-setup.applescript` in the macOS Script Editor. Afterwards copy over the file and rename it to `JabRef-dmg-setup.scpt`.
+Normally the `scpt` file is a binary compiled variant and the `.applescript` the uncompiled format but jpackage expects the sctp in uncompiled format
+
+## Generate iconsets
+
+To generate icns files use the script under `src/main/resources/icons`
+Install [svg2png](https://formulae.brew.sh/formula/svg2png) and call the script with the svg filename as first argument.
diff --git a/buildres/macos/Resources/jabref.icns b/buildres/macos/Resources/jabref.icns
new file mode 100644
index 0000000..e231e8d
Binary files /dev/null and b/buildres/macos/Resources/jabref.icns differ
diff --git a/buildres/macos/Resources/jabrefHost.py b/buildres/macos/Resources/jabrefHost.py
new file mode 100644
index 0000000..815363b
--- /dev/null
+++ b/buildres/macos/Resources/jabrefHost.py
@@ -0,0 +1,101 @@
+#!/usr/bin/python3
+
+import json
+import logging
+import platform
+import shlex
+import shutil
+import struct
+import subprocess
+import sys
+from pathlib import Path
+
+# We assume that this python script is located in "jabref/lib" while the executable is "jabref/bin/JabRef"
+# Note that the package structure is different when installed as a .app bundle on MacOs, so the path must be altered.
+script_dir = Path(__file__).resolve().parent.parent
+JABREF_PATH = script_dir / "bin/JabRef"
+
+# on mac we must only two folder upwards
+if sys.platform.startswith('darwin'):
+ script_dir = Path(__file__).resolve().parent.parent
+if not JABREF_PATH.exists():
+ JABREF_PATH = script_dir / "MacOS/JabRef"
+
+if not JABREF_PATH.exists():
+ logging.error("Could not determine JABREF_PATH")
+ send_message({"message": "error", "output": "Could not find JabRef. Please check that it is installed correctly."})
+ sys.exit(-1)
+
+logging_dir = Path.home() / ".mozilla/native-messaging-hosts/"
+if not logging_dir.exists():
+ logging_dir.mkdir(parents=True)
+logging.basicConfig(filename=str(logging_dir / "jabref_browser_extension.log"))
+
+# Read a message from stdin and decode it.
+def get_message():
+ raw_length = sys.stdin.buffer.read(4)
+ if not raw_length:
+ logging.error("Raw_length null")
+ sys.exit(0)
+ message_length = struct.unpack("=I", raw_length)[0]
+ logging.info("Got length: {} bytes to be read".format(message_length))
+ message = sys.stdin.buffer.read(message_length).decode("utf-8")
+ logging.info("Got message of {} chars".format(len(message)))
+ data = json.loads(message)
+ logging.info("Successfully retrieved JSON")
+ return data
+
+
+# Encode a message for transmission, given its content.
+def encode_message(message_content):
+ encoded_content = json.dumps(message_content).encode("utf-8")
+ encoded_length = struct.pack("=I", len(encoded_content))
+ return {
+ "length": encoded_length,
+ "content": struct.pack(str(len(encoded_content)) + "s", encoded_content),
+ }
+
+
+# Send an encoded message to stdout.
+def send_message(message):
+ encoded_message = encode_message(message)
+ sys.stdout.buffer.write(encoded_message["length"])
+ sys.stdout.buffer.write(encoded_message["content"])
+ sys.stdout.buffer.flush()
+
+
+def add_jabref_entry(data):
+ """Send string via cli as literal to preserve special characters"""
+ cmd = str(JABREF_PATH).split() + ["--importBibtex", r"{}".format(data)]
+ logging.info("Try to execute command {}".format(cmd))
+ response = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ logging.info("Called JabRef and got: {}".format(response))
+ return response
+
+
+logging.info("Starting JabRef backend")
+
+try:
+ message = get_message()
+except Exception as e:
+ message = str(e)
+logging.info(str(message))
+
+if "status" in message and message["status"] == "validate":
+ cmd = str(JABREF_PATH).split() + ["--version"]
+ try:
+ response = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+ except subprocess.CalledProcessError as exc:
+ logging.error("Failed to call JabRef: {} {}".format(exc.returncode, exc.output))
+ send_message({"message": "jarNotFound", "path": JABREF_PATH})
+ else:
+ logging.info("Response: {}".format(response))
+ send_message({"message": "jarFound"})
+else:
+ entry = message["text"]
+ try:
+ output = add_jabref_entry(entry)
+ send_message({"message": "ok", "output": str(output)})
+ except subprocess.CalledProcessError as exc:
+ logging.error("Failed to call JabRef: {} {}".format(exc.returncode, exc.output))
+ send_message({"message": "error", "output": str(exc.output)})
diff --git a/buildres/macos/Resources/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json b/buildres/macos/Resources/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json
new file mode 100644
index 0000000..17f681d
--- /dev/null
+++ b/buildres/macos/Resources/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json
@@ -0,0 +1,3 @@
+{
+ "external_update_url": "https://clients2.google.com/service/update2/crx"
+}
diff --git a/buildres/macos/Resources/native-messaging-host/chromium/org.jabref.jabref.json b/buildres/macos/Resources/native-messaging-host/chromium/org.jabref.jabref.json
new file mode 100644
index 0000000..e07d623
--- /dev/null
+++ b/buildres/macos/Resources/native-messaging-host/chromium/org.jabref.jabref.json
@@ -0,0 +1,10 @@
+{
+ "name": "org.jabref.jabref",
+ "description": "JabRef",
+ "path": "/Applications/JabRef.app/Contents/Resources/jabrefHost.py",
+ "type": "stdio",
+ "allowed_origins": [
+ "chrome-extension://bifehkofibaamoeaopjglfkddgkijdlh/",
+ "chrome-extension://pgkajmkfgbehiomipedjhoddkejohfna/"
+ ]
+}
diff --git a/buildres/macos/Resources/native-messaging-host/firefox/org.jabref.jabref.json b/buildres/macos/Resources/native-messaging-host/firefox/org.jabref.jabref.json
new file mode 100644
index 0000000..66177c6
--- /dev/null
+++ b/buildres/macos/Resources/native-messaging-host/firefox/org.jabref.jabref.json
@@ -0,0 +1,7 @@
+{
+ "name": "org.jabref.jabref",
+ "description": "JabRef",
+ "path": "/Applications/JabRef.app/Contents/Resources/jabrefHost.py",
+ "type": "stdio",
+ "allowed_extensions": ["browserextension@jabref.org", "@jabfox"]
+}
diff --git a/buildres/macos/Runtime-Info.plist b/buildres/macos/Runtime-Info.plist
new file mode 100644
index 0000000..76fb7ee
--- /dev/null
+++ b/buildres/macos/Runtime-Info.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleExecutable
+ libjli.dylib
+ CFBundleIdentifier
+ CF_BUNDLE_IDENTIFIER
+ CFBundleInfoDictionaryVersion
+ 7.0
+ CFBundleName
+ CF_BUNDLE_NAME
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ CF_BUNDLE_SHORT_VERSION_STRING
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ CF_BUNDLE_VERSION
+ NSSupportsAutomaticGraphicsSwitching
+
+
+
diff --git a/buildres/macos/Runtime-Info.plist.template b/buildres/macos/Runtime-Info.plist.template
new file mode 100644
index 0000000..76fb7ee
--- /dev/null
+++ b/buildres/macos/Runtime-Info.plist.template
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ English
+ CFBundleExecutable
+ libjli.dylib
+ CFBundleIdentifier
+ CF_BUNDLE_IDENTIFIER
+ CFBundleInfoDictionaryVersion
+ 7.0
+ CFBundleName
+ CF_BUNDLE_NAME
+ CFBundlePackageType
+ BNDL
+ CFBundleShortVersionString
+ CF_BUNDLE_SHORT_VERSION_STRING
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ CF_BUNDLE_VERSION
+ NSSupportsAutomaticGraphicsSwitching
+
+
+
diff --git a/buildres/macos/bibtexAssociations.properties b/buildres/macos/bibtexAssociations.properties
new file mode 100644
index 0000000..a083986
--- /dev/null
+++ b/buildres/macos/bibtexAssociations.properties
@@ -0,0 +1,3 @@
+extension=bib
+mime-type=text/x-bibtex
+description=BibTeX File
diff --git a/buildres/macos/info-lite.plist b/buildres/macos/info-lite.plist
new file mode 100644
index 0000000..509eb84
--- /dev/null
+++ b/buildres/macos/info-lite.plist
@@ -0,0 +1,39 @@
+
+
+
+
+ LSMinimumSystemVersion
+ 10.9
+ CFBundleDevelopmentRegion
+ English
+ CFBundleAllowMixedLocalizations
+
+ CFBundleExecutable
+ DEPLOY_LAUNCHER_NAME
+ CFBundleIconFile
+ DEPLOY_ICON_FILE
+ CFBundleIdentifier
+ DEPLOY_BUNDLE_IDENTIFIER
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ DEPLOY_BUNDLE_NAME
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ DEPLOY_BUNDLE_SHORT_VERSION
+ CFBundleSignature
+ ????
+
+ LSApplicationCategoryType
+ Unknown
+ CFBundleVersion
+ DEPLOY_BUNDLE_CFBUNDLE_VERSION
+ NSHumanReadableCopyright
+ DEPLOY_BUNDLE_COPYRIGHTDEPLOY_FILE_ASSOCIATIONS
+ NSHighResolutionCapable
+ true
+ NSSupportsAutomaticGraphicsSwitching
+
+
+
diff --git a/buildres/macos/jabref.entitlements b/buildres/macos/jabref.entitlements
new file mode 100644
index 0000000..56f6d63
--- /dev/null
+++ b/buildres/macos/jabref.entitlements
@@ -0,0 +1,24 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.network.server
+
+ com.apple.security.network.client
+
+ com.apple.security.files.user-selected.read-write
+
+ com.apple.security.cs.allow-jit
+
+ com.apple.security.cs.allow-unsigned-executable-memory
+
+ com.apple.security.cs.disable-executable-page-protection
+
+ com.apple.security.cs.disable-library-validation
+
+ com.apple.security.cs.allow-dyld-environment-variables
+
+
+
diff --git a/buildres/macos/jabref.icns b/buildres/macos/jabref.icns
new file mode 100644
index 0000000..e231e8d
Binary files /dev/null and b/buildres/macos/jabref.icns differ
diff --git a/buildres/macos/launcher.icns b/buildres/macos/launcher.icns
new file mode 100644
index 0000000..e231e8d
Binary files /dev/null and b/buildres/macos/launcher.icns differ
diff --git a/buildres/macos/postinstall b/buildres/macos/postinstall
new file mode 100644
index 0000000..3b99d57
--- /dev/null
+++ b/buildres/macos/postinstall
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+chown root:wheel "INSTALL_LOCATION"
+chmod a+rX "INSTALL_LOCATION"
+chmod +r "APP_LOCATION/"*.jar
+# Trigger an auto-install of the browser addon for chrome/chromium browsers
+# First create the necessary path, then copy the autoinstall file.
+install -d /Library/Application\ Support/Google/Chrome/External\ Extensions/
+install -m0644 /Applications/JabRef.app/Contents/Resources/native-messaging-host/chromium/bifehkofibaamoeaopjglfkddgkijdlh.json /Library/Application\ Support/Google/Chrome/External\ Extensions/bifehkofibaamoeaopjglfkddgkijdlh.json
+# Install the native-messaging host script for firefox/chrome/chromium
+install -d /Library/Application\ Support/Mozilla/NativeMessagingHosts/
+install -m0755 /Applications/JabRef.app/Contents/Resources/native-messaging-host/firefox/org.jabref.jabref.json /Library/Application\ Support/Mozilla/NativeMessagingHosts/org.jabref.jabref.json
+install -d /Library/Application\ Support/Chromium/NativeMessagingHosts/
+install -m0755 /Applications/JabRef.app/Contents/Resources/chromium/org.jabref.jabref.json /Library/Application\ Support/Chromium/NativeMessagingHosts/org.jabref.jabref.json
+install -d /Library/Google/Chrome/NativeMessagingHosts/
+install -m0755 /Applications/JabRef.app/Contents/Resources/chromium/org.jabref.jabref.json /Library/Google/Chrome/NativeMessagingHosts/org.jabref.jabref.json
+install -d /Library/Microsoft/Edge/NativeMessagingHosts/
+install -m0755 /Applications/JabRef.app/Contents/Resources/chromium/org.jabref.jabref.json /Library/Microsoft/Edge/NativeMessagingHosts/org.jabref.jabref.json
+
+exit 0