Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--Jenkinsfile6
-rw-r--r--bundles/org.eclipse.swt.tools.base/pom.xml2
-rw-r--r--bundles/org.eclipse.swt.tools.spies/META-INF/MANIFEST.MF4
-rw-r--r--bundles/org.eclipse.swt.tools.spies/fragment.e4xmi4
-rw-r--r--bundles/org.eclipse.swt.tools.spies/pom.xml4
-rw-r--r--bundles/org.eclipse.swt.tools.spies/src/org/eclipse/swt/tools/internal/Sleak.java277
-rw-r--r--bundles/org.eclipse.swt.tools.spies/src/org/eclipse/swt/tools/views/SleakView.java5
-rw-r--r--bundles/org.eclipse.swt.tools/pom.xml2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/JSON.java (renamed from bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/JSON.java)0
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java20
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java71
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java71
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeTableCommon.java89
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java36
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java109
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/build.sh33
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c14
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak33
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c311
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c24
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h24
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkRectangle.java5
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java178
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/build.bat176
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/make_win32.mak2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java7
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c363
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.c616
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.h74
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c20
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h20
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java418
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebkitGDBus.java666
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java67
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java4
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Button.java3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java71
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Table.java83
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tree.java10
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/TreeItem.java12
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java16
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak8
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java11
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/SWTMessages.properties7
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/WidgetSpy.java154
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/BorderData.java120
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/BorderLayout.java420
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/common/version.txt2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java23
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/GDBus.java4
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java8
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java23
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java70
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java1
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java99
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java52
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java104
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java12
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java50
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java117
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java269
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java4
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java10
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java91
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Caret.java21
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java48
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TableColumn.java110
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java16
-rw-r--r--bundles/org.eclipse.swt/META-INF/MANIFEST.MF8
-rw-r--r--bundles/org.eclipse.swt/Readme.Win32.md2
-rw-r--r--bundles/org.eclipse.swt/buildFragment.xml6
-rw-r--r--bundles/org.eclipse.swt/buildSWT.xml19
-rw-r--r--bundles/org.eclipse.swt/pom.xml6
-rw-r--r--container/Dockerfile2
-rw-r--r--examples/org.eclipse.swt.examples.browser.demos/pom.xml2
-rw-r--r--examples/org.eclipse.swt.examples.launcher/pom.xml2
-rw-r--r--examples/org.eclipse.swt.examples.ole.win32/pom.xml2
-rw-r--r--examples/org.eclipse.swt.examples.views/pom.xml2
-rw-r--r--examples/org.eclipse.swt.examples/META-INF/MANIFEST.MF2
-rw-r--r--examples/org.eclipse.swt.examples/pom.xml4
-rw-r--r--examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/controlexample/browser-content.html2
-rw-r--r--examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/imageanalyzer/ImageAnalyzer.java55
-rw-r--r--examples/org.eclipse.swt.snippets/previews/Snippet379.pngbin0 -> 12342 bytes
-rw-r--r--examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet154.java4
-rw-r--r--examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet246.java37
-rw-r--r--examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet337.java2
-rw-r--r--examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet379.java63
-rw-r--r--features/org.eclipse.swt.tools.feature/feature.xml2
-rw-r--r--features/org.eclipse.swt.tools.feature/pom.xml4
-rw-r--r--local-build/local-build-parent/pom.xml2
-rw-r--r--local-build/org.eclipse.swt.fragments.localbuild/pom.xml2
-rw-r--r--pom.xml2
-rw-r--r--tests/org.eclipse.swt.tests.cocoa/ManualTests/org/eclipse/swt/tests/cocoa/snippets/Bug569088_macOS_RadioButtonNotRendered.java42
-rw-r--r--tests/org.eclipse.swt.tests.cocoa/pom.xml2
-rw-r--r--tests/org.eclipse.swt.tests.gtk/META-INF/MANIFEST.MF2
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug525946_DownloadFunction.java4
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug579257_new_webkit_window.java64
-rw-r--r--tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug579283_TestToolbarOverflow_itemEnablement.java104
-rw-r--r--tests/org.eclipse.swt.tests.gtk/pom.xml4
-rw-r--r--tests/org.eclipse.swt.tests.win32/pom.xml2
-rw-r--r--tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java41
-rw-r--r--tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_TextLayout.java63
-rw-r--r--tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_layout_BorderLayout.java173
-rw-r--r--tests/org.eclipse.swt.tests/META-INF/MANIFEST.MF2
-rw-r--r--tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug456602_macOS_AIOOBE_Table_selectedRowIndex.java90
-rw-r--r--tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug546935_TableFlickeringResizingColumns.java101
-rw-r--r--tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577129_Win11_NoButtonArrows.java84
-rw-r--r--tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577878_GTK_TreeTable_NoDragImageWithPaintItem.java216
-rw-r--r--tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug578171_macOS_JvmCrash_ShowMenuWindow.java78
-rw-r--r--tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/SnippetDrawAlpha.java98
-rw-r--r--tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/SnippetDrawAlphaTwoPass.java159
-rw-r--r--tests/org.eclipse.swt.tests/data/eclipse.pngbin0 -> 3353 bytes
-rw-r--r--tests/org.eclipse.swt.tests/data/eclipse16.pngbin0 -> 664 bytes
-rw-r--r--tests/org.eclipse.swt.tests/data/eclipse24.pngbin0 -> 1813 bytes
-rw-r--r--tests/org.eclipse.swt.tests/data/eclipse32.pngbin0 -> 2233 bytes
-rw-r--r--tests/org.eclipse.swt.tests/data/pause.gifbin0 -> 338 bytes
-rw-r--r--tests/org.eclipse.swt.tests/data/run.gifbin0 -> 122 bytes
-rw-r--r--tests/org.eclipse.swt.tests/data/warning.gifbin0 -> 152 bytes
-rw-r--r--tests/org.eclipse.swt.tests/pom.xml4
123 files changed, 4027 insertions, 3351 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..69b47b5ade
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.bat text eol=crlf
diff --git a/Jenkinsfile b/Jenkinsfile
index 53cbd9aa8e..9c77094625 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -21,7 +21,7 @@ spec:
memory: "512Mi"
cpu: "500m"
- name: container
- image: akurtakov/swtbuild@sha256:2cd3dfdea1f250597c9e3797512953c03e2182344e86976c1b60117c5dd36a9e
+ image: akurtakov/swtbuild@sha256:fca953c5f0fa9fadb92b1875c1942f6042f4bd51327d1e1e8e40f39923103fe1
tty: true
command: [ "uid_entrypoint", "cat" ]
resources:
@@ -87,7 +87,7 @@ spec:
checkout scm
}
dir ('eclipse.platform.swt.binaries') {
- checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', timeout: 120]], submoduleCfg: [], userRemoteConfigs: [[url: 'https://git.eclipse.org/r/platform/eclipse.platform.swt.binaries.git']]])
+ checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', timeout: 120, depth: 1, shallow: true]], submoduleCfg: [], userRemoteConfigs: [[url: 'https://git.eclipse.org/r/platform/eclipse.platform.swt.binaries.git']]])
}
}
}
@@ -129,7 +129,7 @@ spec:
}
steps {
container('jnlp') {
- sh "wget https://git.eclipse.org/c/platform/eclipse.platform.releng.aggregator.git/plain/scripts/verifyFreezePeriod.sh"
+ sh "wget https://download.eclipse.org/eclipse/relengScripts/scripts/verifyFreezePeriod.sh"
sh "chmod +x verifyFreezePeriod.sh"
withCredentials([string(credentialsId: 'google-api-key', variable: 'GOOGLE_API_KEY')]) {
sh './verifyFreezePeriod.sh'
diff --git a/bundles/org.eclipse.swt.tools.base/pom.xml b/bundles/org.eclipse.swt.tools.base/pom.xml
index 4781c4b4e0..0b736e7934 100644
--- a/bundles/org.eclipse.swt.tools.base/pom.xml
+++ b/bundles/org.eclipse.swt.tools.base/pom.xml
@@ -14,7 +14,7 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
diff --git a/bundles/org.eclipse.swt.tools.spies/META-INF/MANIFEST.MF b/bundles/org.eclipse.swt.tools.spies/META-INF/MANIFEST.MF
index 91bb72ee99..08b3d9e589 100644
--- a/bundles/org.eclipse.swt.tools.spies/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.swt.tools.spies/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-SymbolicName: org.eclipse.swt.tools.spies;singleton:=true
-Bundle-Version: 3.108.200.qualifier
+Bundle-Version: 3.108.300.qualifier
Bundle-ManifestVersion: 2
Export-Package: org.eclipse.swt.tools.internal,
org.eclipse.swt.tools.views
@@ -12,7 +12,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.4.0",
org.eclipse.swt.tools.base;bundle-version="3.106.0",
org.eclipse.e4.ui.model.workbench;bundle-version="2.1.400",
- org.eclipse.swt;bundle-version="3.110.100",
+ org.eclipse.swt;bundle-version="3.119.0",
org.eclipse.ui;bundle-version="3.113.0",
org.eclipse.e4.ui.di;bundle-version="1.2.600"
Automatic-Module-Name: org.eclipse.swt.tools.spies
diff --git a/bundles/org.eclipse.swt.tools.spies/fragment.e4xmi b/bundles/org.eclipse.swt.tools.spies/fragment.e4xmi
index e38c21a056..ac12910e99 100644
--- a/bundles/org.eclipse.swt.tools.spies/fragment.e4xmi
+++ b/bundles/org.eclipse.swt.tools.spies/fragment.e4xmi
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="ASCII"?>
<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:basic="http://www.eclipse.org/ui/2010/UIModel/application/descriptor/basic" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmi:id="_-LZIEN9kEemzyrbiRClN6A">
<fragments xsi:type="fragment:StringModelFragment" xmi:id="__HWaAN9kEemzyrbiRClN6A" featurename="descriptors" parentElementId="xpath:/">
- <elements xsi:type="basic:PartDescriptor" xmi:id="_GSP6cN9lEemzyrbiRClN6A" elementId="org.eclipse.swt.tools.spies.partdescriptor.sleak" label="Sleak" iconURI="platform:/plugin/org.eclipse.swt.tools.spies/icons/sleak.png" category="SWT Tools" contributionURI="bundleclass://org.eclipse.swt.tools.spies/org.eclipse.swt.tools.views.SleakView">
- <persistedState key="persistState" value="false"/>
+ <elements xsi:type="basic:PartDescriptor" xmi:id="_GSP6cN9lEemzyrbiRClN6A" elementId="org.eclipse.swt.tools.spies.partdescriptor.sleak" label="Sleak" iconURI="platform:/plugin/org.eclipse.swt.tools.spies/icons/sleak.png" category="SWT Tools" closeable="true" contributionURI="bundleclass://org.eclipse.swt.tools.spies/org.eclipse.swt.tools.views.SleakView">
+ <persistedState key="persistState" value="true"/>
<tags>View</tags>
</elements>
</fragments>
diff --git a/bundles/org.eclipse.swt.tools.spies/pom.xml b/bundles/org.eclipse.swt.tools.spies/pom.xml
index 5b6176c44e..70b8a6f430 100644
--- a/bundles/org.eclipse.swt.tools.spies/pom.xml
+++ b/bundles/org.eclipse.swt.tools.spies/pom.xml
@@ -14,11 +14,11 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
<artifactId>org.eclipse.swt.tools.spies</artifactId>
- <version>3.108.200-SNAPSHOT</version>
+ <version>3.108.300-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.swt.tools.spies/src/org/eclipse/swt/tools/internal/Sleak.java b/bundles/org.eclipse.swt.tools.spies/src/org/eclipse/swt/tools/internal/Sleak.java
index 5358aabf22..8d9655d877 100644
--- a/bundles/org.eclipse.swt.tools.spies/src/org/eclipse/swt/tools/internal/Sleak.java
+++ b/bundles/org.eclipse.swt.tools.spies/src/org/eclipse/swt/tools/internal/Sleak.java
@@ -15,10 +15,13 @@ package org.eclipse.swt.tools.internal;
import java.io.*;
import java.util.*;
+import java.util.function.*;
import java.util.stream.*;
import org.eclipse.swt.*;
+import org.eclipse.swt.custom.*;
import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.WidgetSpy.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.widgets.List;
@@ -33,21 +36,22 @@ import org.eclipse.swt.widgets.List;
public class Sleak {
List list;
Canvas canvas;
- Button enableTracking, snapshot, diff, stackTrace, saveAs, save;
+ Button enableTracking, diff, stackTrace, saveAs, save;
Combo diffType;
Text text;
- Label label;
String filterPath = "";
String fileName = "sleakout";
- String selectedName = null;
+ String selectedName;
boolean incrementFileNames = true;
boolean saveImages = true;
- int fileCount = 0;
+ int fileCount;
java.util.List<ObjectWithError> oldObjects = new ArrayList<> ();
java.util.List<ObjectWithError> objects = new ArrayList<> ();
+ NonDisposedWidgetTracker nonDisposedWidgetTracker = new NonDisposedWidgetTracker();
+
public static void main (String [] args) {
DeviceData data = new DeviceData();
data.tracking = true;
@@ -90,71 +94,109 @@ public static void main (String [] args) {
}
public void create (Composite parent) {
- enableTracking = new Button (parent, SWT.CHECK);
- enableTracking.setText ("Enable");
- enableTracking.setToolTipText("Enable Device resource tracking. Only resources allocated once enabled will be tracked. To track devices created before view is created, turn on tracing options, see https://www.eclipse.org/swt/tools.php");
- enableTracking.addListener (SWT.Selection, e -> toggleEnableTracking ());
- enableTracking.setSelection(enableTracking.getDisplay().isTracking());
- canvas = new Canvas (parent, SWT.BORDER);
+
+ SashForm sash = new SashForm(parent, SWT.SMOOTH);
+ sash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ sash.setOrientation(SWT.HORIZONTAL);
+ sash.setVisible(true);
+
+ Composite left = new Composite(sash, 0);
+ left.setLayout(new GridLayout());
+ left.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Composite right = new Composite(sash, 0);
+ right.setLayout(new GridLayout());
+
+ sash.setWeights(new int[] {40,60});
+
+ // Right side
+ canvas = new Canvas (right, SWT.BORDER);
canvas.addListener (SWT.Paint, event -> paintCanvas (event));
canvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 10));
- text = new Text (parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
+ text = new Text (right, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 10));
setVisible(text, false);
- snapshot = new Button (parent, SWT.PUSH);
- snapshot.setText ("Snap");
- snapshot.addListener (SWT.Selection, event -> refreshAll ());
- snapshot.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false, false));
- diff = new Button (parent, SWT.PUSH);
- diff.setText ("Diff");
+
+ // Left side
+ enableTracking = new Button (left, SWT.CHECK);
+ enableTracking.setText ("Enable resource tracking");
+ enableTracking.setToolTipText("Enable Device resource tracking. Only resources allocated once enabled will be tracked. To track devices created before view is created, turn on tracing options, see https://www.eclipse.org/swt/tools.php");
+ enableTracking.addListener (SWT.Selection, e -> toggleEnableTracking ());
+ enableTracking.setSelection(enableTracking.getDisplay().isTracking());
+ enableTracking.setLayoutData(new GridData(SWT.NONE, SWT.NONE, false, false));
+
+ Composite buttons = new Composite(left, 0);
+ buttons.setLayout(new GridLayout(4, false));
+ buttons.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
+
+ diff = new Button (buttons, SWT.PUSH);
+ diff.setText ("Snap && Diff");
diff.addListener (SWT.Selection, event -> refreshDifference ());
- diff.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false, false));
- diffType = new Combo (parent, SWT.CHECK);
+ GridData diffData = new GridData(SWT.FILL, SWT.NONE, true, false);
+ diffData.horizontalSpan = 2;
+ diff.setLayoutData(diffData);
+
+ save = new Button (buttons, SWT.PUSH);
+ save.setText ("Save");
+ save.setToolTipText("Saves to the previously selected file.");
+ save.addListener (SWT.Selection, event -> saveToFile (false));
+ save.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false, false));
+
+ saveAs = new Button (buttons, SWT.PUSH);
+ saveAs.setText ("Save As...");
+ saveAs.setToolTipText("Saves the contents of the list to a file, optionally with the stack traces if selected.");
+ saveAs.addListener (SWT.Selection, event -> saveToFile (true));
+ saveAs.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false, false));
+
+ Composite checkboxAndCombo = new Composite(left, 0);
+ checkboxAndCombo.setLayout(new GridLayout(2, false));
+ checkboxAndCombo.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
+
+ diffType = new Combo (checkboxAndCombo, SWT.CHECK);
diffType.add ("Object identity");
diffType.add ("Creator class and line");
diffType.add ("Creator class");
diffType.select(0);
- diffType.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false, false));
- stackTrace = new Button (parent, SWT.CHECK);
- stackTrace.setText ("Stack");
+ diffType.setLayoutData(new GridData(SWT.NONE, SWT.NONE, false, false));
+
+ stackTrace = new Button (checkboxAndCombo, SWT.CHECK);
+ stackTrace.setText ("Show Stack");
stackTrace.addListener (SWT.Selection, e -> toggleStackTrace ());
- list = new List (parent, SWT.BORDER | SWT.V_SCROLL);
+ stackTrace.setLayoutData(new GridData(SWT.RIGHT, SWT.NONE, true, false));
+
+ list = new List (left, SWT.BORDER | SWT.V_SCROLL);
list.addListener (SWT.Selection, event -> refreshObject ());
- list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true));
- label = new Label (parent, SWT.NONE);
- label.setText ("0 object(s)");
- saveAs = new Button (parent, SWT.PUSH);
- saveAs.setText ("Save As...");
- saveAs.setToolTipText("Saves the contents of the list to a file, optionally with the stack traces if selected.");
- saveAs.addListener (SWT.Selection, event -> saveToFile (true));
- saveAs.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false, false));
- save = new Button (parent, SWT.PUSH);
- save.setText ("Save");
- save.setToolTipText("Saves to the previously selected file.");
- save.addListener (SWT.Selection, event -> saveToFile (false));
- save.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false, false));
+ list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
stackTrace.setSelection (false);
+ filterNonDisposedWidgetTypes();
}
private void toggleEnableTracking() {
Display display = enableTracking.getDisplay();
boolean tracking = display.isTracking();
display.setTracking(!tracking);
+ setWidgetTrackingEnabled(tracking);
}
-void refreshLabel () {
- Map<String, Long> deleted = oldObjects.stream().collect(
- Collectors.groupingBy(o -> o.object.getClass().getSimpleName(), Collectors.counting()));
- Map<String, Long> created = objects.stream().collect(
- Collectors.groupingBy(o -> o.object.getClass().getSimpleName(), Collectors.counting()));
+void refreshLabel (java.util.List<ObjectWithError> createdObjects, java.util.List<ObjectWithError> deletedObjects) {
+ Function<? super ObjectWithError, ? extends String> classifier = o -> o.object.getClass().getSimpleName();
+
+ Map<String, Long> deleted = deletedObjects.stream().collect(
+ Collectors.groupingBy(classifier, Collectors.counting()));
+
+ Map<String, Long> created = createdObjects.stream().collect(
+ Collectors.groupingBy(classifier, Collectors.counting()));
+
StringBuilder sb = new StringBuilder();
- Stream.concat(deleted.keySet().stream(), created.keySet().stream()).distinct().sorted().
- forEach(type -> addCounts(sb, type, deleted.get(type), created.get(type)));
- label.setText (sb.length() > 0 ? sb.toString() : "0 object(s)");
- canvas.getParent().layout();
+ Stream<String> deletedAndCreated = Stream.concat(deleted.keySet().stream(), created.keySet().stream());
+ deletedAndCreated.distinct().sorted().forEach(type -> addCounts(sb, type, deleted.get(type), created.get(type)));
+
+ String description = sb.length() > 0 ? sb.toString() : "0 object(s)";
+ list.setToolTipText(description);
}
-void addCounts (StringBuilder string, String type, Long deleted, Long created) {
+static void addCounts (StringBuilder string, String type, Long deleted, Long created) {
if (deleted != null || created != null) {
if (deleted != null) {
string.append("-" + deleted);
@@ -171,57 +213,104 @@ void addCounts (StringBuilder string, String type, Long deleted, Long created) {
void refreshDifference () {
Display display = canvas.getDisplay();
- DeviceData info = display.getDeviceData ();
- if (!info.tracking) {
- Shell shell = canvas.getShell();
- MessageBox dialog = new MessageBox (shell, SWT.ICON_WARNING | SWT.YES | SWT.NO);
- dialog.setText (shell.getText ());
- dialog.setMessage ("Warning: Device is not tracking resource allocation\nWould you like to enable tracking now for future created resources?");
- if (SWT.YES == dialog.open ()) {
- enableTracking.setSelection(true);
- toggleEnableTracking();
+ DeviceData info = getDeviceData(display);
+
+ boolean hasOldData = !oldObjects.isEmpty();
+
+ java.util.List<ObjectWithError> old = new ArrayList<>(oldObjects);
+ java.util.List<ObjectWithError> disposed = new ArrayList<>();
+ java.util.List<ObjectWithError> created = new ArrayList<>();
+ java.util.List<ObjectWithError> same = collectNewObjects(info, old, disposed, created);
+ java.util.List<ObjectWithError> nonDisposedWidgets = getNonDisposedWidgets();
+ created.addAll(nonDisposedWidgets);
+ resetNonDisposedWidgets();
+
+ if (diffType.getSelectionIndex() > 0) {
+ old.removeAll(same);
+ if (!old.isEmpty()) {
+ Iterator<ObjectWithError> createdIter = created.iterator ();
+ while (createdIter.hasNext ()) {
+ ObjectWithError createdObj = createdIter.next ();
+ StackTraceElement stack = createdObj.getCreator ();
+ Iterator<ObjectWithError> oldIter = old.iterator ();
+ while (oldIter.hasNext ()) {
+ ObjectWithError oldObj = oldIter.next();
+ if (creatorEquals(stack, oldObj.getCreator ())) {
+ createdIter.remove ();
+ break;
+ }
+ }
+ }
}
}
+
+ objects.clear();
+ objects.addAll(created);
+
+ oldObjects.clear();
+ oldObjects.addAll(same);
+ oldObjects.addAll(created);
+
+
+ list.removeAll ();
+ text.setText ("");
+ canvas.redraw ();
+ if(hasOldData) {
+ for (ObjectWithError object : created) {
+ list.add (object.object.toString());
+ }
+ }
+ if(hasOldData) {
+ refreshLabel (created, disposed);
+ } else {
+ refreshLabel (Collections.emptyList(), Collections.emptyList());
+ }
+}
+
+private static java.util.List<ObjectWithError> collectNewObjects(DeviceData info,
+ java.util.List<ObjectWithError> oldObjects,
+ java.util.List<ObjectWithError> disposedObjects,
+ java.util.List<ObjectWithError> createdObjects
+ ) {
+ disposedObjects.addAll(oldObjects);
+ ArrayList<ObjectWithError> sameObjects = new ArrayList<>();
- oldObjects = new ArrayList<> (objects);
- objects.clear ();
for (int i=0; i<info.objects.length; i++) {
boolean found = false;
Iterator<ObjectWithError> oldObject = oldObjects.iterator ();
- if (!(info.objects [i] instanceof Color)) {
+ Object infoObject = info.objects [i];
+ if (!(infoObject instanceof Color)) {
// Bug 563018: Colors don't require disposal, so exclude them from the list of allocated objects.
while (oldObject.hasNext () && !found) {
- if (info.objects [i] == oldObject.next ().object) {
- oldObject.remove ();
+ ObjectWithError next = oldObject.next ();
+ if (infoObject == next.object) {
+ sameObjects.add(next);
found = true;
}
}
if (!found) {
- objects.add (new ObjectWithError (info.objects [i], info.errors[i]));
+ createdObjects.add(new ObjectWithError (infoObject, info.errors[i]));
}
}
}
- if (diffType.getSelectionIndex() > 0) {
- Iterator<ObjectWithError> object = objects.iterator ();
- while (object.hasNext ()) {
- StackTraceElement stack = object.next ().getCreator ();
- Iterator<ObjectWithError> old = oldObjects.iterator ();
- while (old.hasNext ()) {
- if (creatorEquals(stack, old.next().getCreator ())) {
- old.remove ();
- object.remove ();
- break;
- }
- }
+ // objects that were not found in new system state are disposed
+ disposedObjects.removeAll(sameObjects);
+ return sameObjects;
+}
+
+private DeviceData getDeviceData(Display display) {
+ DeviceData info = display.getDeviceData ();
+ if (!info.tracking) {
+ Shell shell = canvas.getShell();
+ MessageBox dialog = new MessageBox (shell, SWT.ICON_WARNING | SWT.YES | SWT.NO);
+ dialog.setText (shell.getText ());
+ dialog.setMessage ("Warning: Device is not tracking resource allocation\nWould you like to enable tracking now for future created resources?");
+ if (SWT.YES == dialog.open ()) {
+ enableTracking.setSelection(true);
+ toggleEnableTracking();
}
}
- list.removeAll ();
- text.setText ("");
- canvas.redraw ();
- for (ObjectWithError object : objects) {
- list.add (object.object.toString());
- }
- refreshLabel ();
+ return info;
}
boolean creatorEquals (StackTraceElement first, StackTraceElement second) {
@@ -261,7 +350,7 @@ private void saveToFile(boolean prompt) {
fileName = String.format("%s_%03d", fileName, fileCount++);
}
try (PrintWriter file = new PrintWriter(new FileOutputStream(fileName))) {
-
+
int i = 0;
for (ObjectWithError o : objects) {
Object object = o.object;
@@ -386,7 +475,7 @@ void refreshObject () {
text.setText (objects.get(index).getStack());
setVisible(text, true);
setVisible(canvas, false);
- canvas.getParent().layout();
+ text.getParent().layout();
} else {
setVisible(canvas, true);
setVisible(text, false);
@@ -399,10 +488,26 @@ private void setVisible(Control control, boolean visible) {
((GridData)control.getLayoutData()).exclude = !visible;
}
-void refreshAll () {
- objects.clear();
- refreshDifference ();
- oldObjects = new ArrayList<>(objects);
+private void filterNonDisposedWidgetTypes() {
+ java.util.List<Class<? extends Widget>> trackedTypes = Arrays.asList(
+// Composite.class,
+// Menu.class
+ );
+ nonDisposedWidgetTracker.setTrackedTypes(trackedTypes);
+}
+
+private void setWidgetTrackingEnabled(boolean tracking) {
+ nonDisposedWidgetTracker.setTrackingEnabled(tracking);
+}
+
+private java.util.List<ObjectWithError> getNonDisposedWidgets() {
+ java.util.List<ObjectWithError> nonDisposedWidgets = new ArrayList<>();
+ nonDisposedWidgetTracker.getNonDisposedWidgets().forEach((w, e) -> nonDisposedWidgets.add(new ObjectWithError(w, e)));
+ return nonDisposedWidgets;
+}
+
+private void resetNonDisposedWidgets() {
+ nonDisposedWidgetTracker.startTracking();
}
private static final class ObjectWithError {
diff --git a/bundles/org.eclipse.swt.tools.spies/src/org/eclipse/swt/tools/views/SleakView.java b/bundles/org.eclipse.swt.tools.spies/src/org/eclipse/swt/tools/views/SleakView.java
index 1f4203f700..e3985864e5 100644
--- a/bundles/org.eclipse.swt.tools.spies/src/org/eclipse/swt/tools/views/SleakView.java
+++ b/bundles/org.eclipse.swt.tools.spies/src/org/eclipse/swt/tools/views/SleakView.java
@@ -17,7 +17,6 @@ package org.eclipse.swt.tools.views;
import javax.annotation.*;
import org.eclipse.e4.ui.di.*;
-import org.eclipse.swt.*;
import org.eclipse.swt.tools.internal.*;
import org.eclipse.swt.widgets.*;
@@ -31,9 +30,9 @@ public class SleakView {
@PostConstruct
public void createPartControl(Composite parent) {
- composite = new Composite(parent, SWT.NONE);
Sleak sleak = new Sleak ();
- sleak.create(composite);
+ sleak.create(parent);
+ composite = parent;
}
@Focus
diff --git a/bundles/org.eclipse.swt.tools/pom.xml b/bundles/org.eclipse.swt.tools/pom.xml
index e281b98ad9..93a15ed588 100644
--- a/bundles/org.eclipse.swt.tools/pom.xml
+++ b/bundles/org.eclipse.swt.tools/pom.xml
@@ -14,7 +14,7 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/JSON.java b/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/JSON.java
index 2730297b9f..2730297b9f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/JSON.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Browser/common/org/eclipse/swt/browser/JSON.java
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
index a3fed244b6..d0dce59089 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/StyledText.java
@@ -8962,6 +8962,7 @@ void setCaretLocations(final Point[] locations, int direction) {
carets[i] = new Caret(this, firstCaret.getStyle());
carets[i].setImage(firstCaret.getImage());
carets[i].setFont(firstCaret.getFont());
+ carets[i].setSize(firstCaret.getSize());
}
} else if (locations.length < carets.length) {
for (int i = locations.length; i < carets.length; i++) {
@@ -8969,7 +8970,7 @@ void setCaretLocations(final Point[] locations, int direction) {
}
carets = Arrays.copyOf(carets, locations.length);
}
- for (int i = 0; i < Math.min(caretOffsets.length, locations.length); i++) {
+ for (int i = Math.min(caretOffsets.length, locations.length)-1; i>=0; i--) { // reverse order, seee bug 579028#c7
final Caret caret = carets[i];
final int caretOffset = caretOffsets[i];
final Point location = locations[i];
@@ -9053,6 +9054,7 @@ void setCaretLocations(final Point[] locations, int direction) {
}
}
updateCaretVisibility();
+ super.redraw();
}
columnX = locations[0].x;
}
@@ -9239,6 +9241,21 @@ public void setEnabled(boolean enabled) {
this.insideSetEnableCall = false;
}
}
+
+@Override
+public boolean setFocus() {
+ boolean focusGained = super.setFocus();
+ if (focusGained && hasMultipleCarets()) {
+ // Multiple carets need to update their drawing. See bug 579179
+ setCaretLocations();
+ }
+ return focusGained;
+}
+
+private boolean hasMultipleCarets() {
+ return carets != null && carets.length > 1;
+}
+
/**
* Sets a new font to render text with.
* <p>
@@ -11275,7 +11292,6 @@ void updateCaretVisibility() {
c.setVisible(visible);
});
}
- redraw();
}
}
/**
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java
index af900f9731..7dc98a6f7f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java
@@ -13,10 +13,7 @@
*******************************************************************************/
package org.eclipse.swt.dnd;
-import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.internal.cairo.*;
-import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.widgets.*;
/**
@@ -83,73 +80,7 @@ public class TableDragSourceEffect extends DragSourceEffect {
Image getDragSourceImage(DragSourceEvent event) {
if (dragSourceImage != null) dragSourceImage.dispose();
- dragSourceImage = null;
-
- Table table = (Table) control;
- //TEMPORARY CODE
- if (table.isListening(SWT.EraseItem) || table.isListening (SWT.PaintItem)) return null;
-
- /*
- * Bug in GTK. gtk_tree_selection_get_selected_rows() segmentation faults
- * in versions smaller than 2.2.4 if the model is NULL. The fix is
- * to give a valid pointer instead.
- */
- long handle = table.handle;
- long selection = GTK.gtk_tree_view_get_selection (handle);
- long [] model = null;
- long list = GTK.gtk_tree_selection_get_selected_rows (selection, model);
- if (list == 0) return null;
- int count = Math.min(10, OS.g_list_length (list));
- long originalList = list;
-
- Display display = table.getDisplay();
- if (count == 1) {
- long path = OS.g_list_nth_data (list, 0);
- long icon = GTK.gtk_tree_view_create_row_drag_icon (handle, path);
- dragSourceImage = Image.gtk_new (display, SWT.ICON, icon, 0);
- GTK.gtk_tree_path_free (path);
- } else {
- int width = 0, height = 0;
- int[] w = new int[1], h = new int[1];
- int[] yy = new int[count], hh = new int[count];
- long [] icons = new long [count];
- GdkRectangle rect = new GdkRectangle ();
- for (int i=0; i<count; i++) {
- long path = OS.g_list_data (list);
- GTK.gtk_tree_view_get_cell_area (handle, path, 0, rect);
- icons[i] = GTK.gtk_tree_view_create_row_drag_icon(handle, path);
- switch (Cairo.cairo_surface_get_type(icons[i])) {
- case Cairo.CAIRO_SURFACE_TYPE_IMAGE:
- w[0] = Cairo.cairo_image_surface_get_width(icons[i]);
- h[0] = Cairo.cairo_image_surface_get_height(icons[i]);
- break;
- case Cairo.CAIRO_SURFACE_TYPE_XLIB:
- w[0] = Cairo.cairo_xlib_surface_get_width(icons[i]);
- h[0] = Cairo.cairo_xlib_surface_get_height(icons[i]);
- break;
- }
- width = Math.max(width, w[0]);
- height = rect.y + h[0] - yy[0];
- yy[i] = rect.y;
- hh[i] = h[0];
- list = OS.g_list_next (list);
- GTK.gtk_tree_path_free (path);
- }
- long surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_ARGB32, width, height);
- if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
- long cairo = Cairo.cairo_create(surface);
- if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
- Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_SOURCE);
- for (int i=0; i<count; i++) {
- Cairo.cairo_set_source_surface (cairo, icons[i], 2, yy[i] - yy[0] + 2);
- Cairo.cairo_rectangle(cairo, 0, yy[i] - yy[0], width, hh[i]);
- Cairo.cairo_fill(cairo);
- Cairo.cairo_surface_destroy(icons[i]);
- }
- Cairo.cairo_destroy(cairo);
- dragSourceImage = Image.gtk_new (display, SWT.ICON, surface, 0);
- }
- OS.g_list_free (originalList);
+ dragSourceImage = TreeTableCommon.getDragSourceImage(control);
return dragSourceImage;
}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java
index d48a177f1c..f6eb7614c9 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java
@@ -13,10 +13,7 @@
*******************************************************************************/
package org.eclipse.swt.dnd;
-import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
-import org.eclipse.swt.internal.cairo.*;
-import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.widgets.*;
/**
@@ -82,73 +79,7 @@ public class TreeDragSourceEffect extends DragSourceEffect {
Image getDragSourceImage(DragSourceEvent event) {
if (dragSourceImage != null) dragSourceImage.dispose();
- dragSourceImage = null;
-
- Tree tree = (Tree) control;
- //TEMPORARY CODE
- if (tree.isListening(SWT.EraseItem) || tree.isListening (SWT.PaintItem)) return null;
-
- /*
- * Bug in GTK. gtk_tree_selection_get_selected_rows() segmentation faults
- * in versions smaller than 2.2.4 if the model is NULL. The fix is
- * to give a valid pointer instead.
- */
- long handle = tree.handle;
- long selection = GTK.gtk_tree_view_get_selection (handle);
- long [] model = null;
- long list = GTK.gtk_tree_selection_get_selected_rows (selection, model);
- if (list == 0) return null;
- int count = Math.min(10, OS.g_list_length (list));
- long originalList = list;
-
- Display display = tree.getDisplay();
- if (count == 1) {
- long path = OS.g_list_nth_data (list, 0);
- long icon = GTK.gtk_tree_view_create_row_drag_icon (handle, path);
- dragSourceImage = Image.gtk_new (display, SWT.ICON, icon, 0);
- GTK.gtk_tree_path_free (path);
- } else {
- int width = 0, height = 0;
- int[] w = new int[1], h = new int[1];
- int[] yy = new int[count], hh = new int[count];
- long [] icons = new long [count];
- GdkRectangle rect = new GdkRectangle ();
- for (int i=0; i<count; i++) {
- long path = OS.g_list_data (list);
- GTK.gtk_tree_view_get_cell_area (handle, path, 0, rect);
- icons[i] = GTK.gtk_tree_view_create_row_drag_icon(handle, path);
- switch (Cairo.cairo_surface_get_type(icons[i])) {
- case Cairo.CAIRO_SURFACE_TYPE_IMAGE:
- w[0] = Cairo.cairo_image_surface_get_width(icons[i]);
- h[0] = Cairo.cairo_image_surface_get_height(icons[i]);
- break;
- case Cairo.CAIRO_SURFACE_TYPE_XLIB:
- w[0] = Cairo.cairo_xlib_surface_get_width(icons[i]);
- h[0] = Cairo.cairo_xlib_surface_get_height(icons[i]);
- break;
- }
- width = Math.max(width, w[0]);
- height = rect.y + h[0] - yy[0];
- yy[i] = rect.y;
- hh[i] = h[0];
- list = OS.g_list_next (list);
- GTK.gtk_tree_path_free (path);
- }
- long surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_ARGB32, width, height);
- if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
- long cairo = Cairo.cairo_create(surface);
- if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
- Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_SOURCE);
- for (int i=0; i<count; i++) {
- Cairo.cairo_set_source_surface (cairo, icons[i], 2, yy[i] - yy[0] + 2);
- Cairo.cairo_rectangle(cairo, 0, yy[i] - yy[0], width, hh[i]);
- Cairo.cairo_fill(cairo);
- Cairo.cairo_surface_destroy(icons[i]);
- }
- Cairo.cairo_destroy(cairo);
- dragSourceImage = Image.gtk_new (display, SWT.ICON, surface, 0);
- }
- OS.g_list_free (originalList);
+ dragSourceImage = TreeTableCommon.getDragSourceImage(control);
return dragSourceImage;
}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeTableCommon.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeTableCommon.java
new file mode 100644
index 0000000000..24560166d3
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeTableCommon.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2022 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.dnd;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.cairo.*;
+import org.eclipse.swt.internal.gtk.*;
+import org.eclipse.swt.widgets.*;
+
+class TreeTableCommon {
+ static Image getDragSourceImage(Control control) {
+ Image dragSourceImage;
+
+ /*
+ * Bug in GTK. gtk_tree_selection_get_selected_rows() segmentation faults
+ * in versions smaller than 2.2.4 if the model is NULL. The fix is
+ * to give a valid pointer instead.
+ */
+ long handle = control.handle;
+ long selection = GTK.gtk_tree_view_get_selection (handle);
+ long [] model = null;
+ long list = GTK.gtk_tree_selection_get_selected_rows (selection, model);
+ if (list == 0) return null;
+ int count = Math.min(10, OS.g_list_length (list));
+ long originalList = list;
+
+ Display display = control.getDisplay();
+ if (count == 1) {
+ long path = OS.g_list_nth_data (list, 0);
+ long icon = GTK.gtk_tree_view_create_row_drag_icon (handle, path);
+ dragSourceImage = Image.gtk_new (display, SWT.ICON, icon, 0);
+ GTK.gtk_tree_path_free (path);
+ } else {
+ int width = 0, height = 0;
+ int[] w = new int[1], h = new int[1];
+ int[] yy = new int[count], hh = new int[count];
+ long [] icons = new long [count];
+ GdkRectangle rect = new GdkRectangle ();
+ for (int i=0; i<count; i++) {
+ long path = OS.g_list_data (list);
+ GTK.gtk_tree_view_get_cell_area (handle, path, 0, rect);
+ icons[i] = GTK.gtk_tree_view_create_row_drag_icon(handle, path);
+ switch (Cairo.cairo_surface_get_type(icons[i])) {
+ case Cairo.CAIRO_SURFACE_TYPE_IMAGE:
+ w[0] = Cairo.cairo_image_surface_get_width(icons[i]);
+ h[0] = Cairo.cairo_image_surface_get_height(icons[i]);
+ break;
+ case Cairo.CAIRO_SURFACE_TYPE_XLIB:
+ w[0] = Cairo.cairo_xlib_surface_get_width(icons[i]);
+ h[0] = Cairo.cairo_xlib_surface_get_height(icons[i]);
+ break;
+ }
+ width = Math.max(width, w[0]);
+ height = rect.y + h[0] - yy[0];
+ yy[i] = rect.y;
+ hh[i] = h[0];
+ list = OS.g_list_next (list);
+ GTK.gtk_tree_path_free (path);
+ }
+ long surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_ARGB32, width, height);
+ if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ long cairo = Cairo.cairo_create(surface);
+ if (cairo == 0) SWT.error(SWT.ERROR_NO_HANDLES);
+ Cairo.cairo_set_operator(cairo, Cairo.CAIRO_OPERATOR_SOURCE);
+ for (int i=0; i<count; i++) {
+ Cairo.cairo_set_source_surface (cairo, icons[i], 2, yy[i] - yy[0] + 2);
+ Cairo.cairo_rectangle(cairo, 0, yy[i] - yy[0], width, hh[i]);
+ Cairo.cairo_fill(cairo);
+ Cairo.cairo_surface_destroy(icons[i]);
+ }
+ Cairo.cairo_destroy(cairo);
+ dragSourceImage = Image.gtk_new (display, SWT.ICON, surface, 0);
+ }
+ OS.g_list_free (originalList);
+ return dragSourceImage;
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
index 3ec3241774..d8bb1b5091 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2021 IBM Corporation and others.
+ * Copyright (c) 2007, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -21,6 +21,17 @@ public class OS extends C {
Library.loadLibrary("swt-pi"); //$NON-NLS-1$
}
+ /*
+ * macOS version, encoded as ((major << 16) + (minor << 8) + bugfix).
+ *
+ * Note that for macOS >= 11, it has "wrong" values if executable's
+ * SDK is below 10.15 (or is it 11.0?), where 10.16.0 is reported
+ * regardless of actual macOS version. On the other hand, with good
+ * executable's SDK, real version is reported.
+ *
+ * This also means that executables with old SDK can't distinguish
+ * macOS 11 from macOS 12.
+ */
public static final int VERSION;
public static int VERSION (int major, int minor, int bugfix) {
@@ -167,6 +178,24 @@ public class OS extends C {
* Custom message that will be sent when setTheme is called for example from Platform UI code.
*/
public static final long sel_appAppearanceChanged = OS.sel_registerName("appAppearanceChanged");
+
+ /**
+ * Experimental API for dark theme.
+ * <p>
+ * On Windows, there is no OS API for dark theme yet, and this method only
+ * configures various tweaks. Some of these tweaks have drawbacks. The tweaks
+ * are configured with defaults that fit Eclipse. Non-Eclipse applications are
+ * expected to configure individual tweaks instead of calling this method.
+ * Please see <code>Display#setData()</code> and documentation for string keys
+ * used there.
+ * </p>
+ * <p>
+ * On GTK, behavior may be different as the boolean flag doesn't force dark
+ * theme instead it specify that dark theme is preferred.
+ * </p>
+ *
+ * @param isDarkTheme <code>true</code> for dark theme
+ */
public static void setTheme(boolean isDarkTheme) {
OS.objc_msgSend(NSApplication.sharedApplication().id, sel_appAppearanceChanged, isDarkTheme ? 1 : 0);
}
@@ -190,10 +219,7 @@ public class OS extends C {
* @return true for macOS BigSur or later, returns false for macOS 10.15 and older
*/
public static boolean isBigSurOrLater () {
- /*
- * Currently Big Sur OS version matches with 10.16 and not 11.0. This may be temporary.
- * Creating a method, so that it can be fixed in one place if/when this changes.
- */
+ // See comment for OS.VERSION for an explanation
return OS.VERSION >= OS.VERSION(10, 16, 0);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java b/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java
index c630b9932d..5902733d19 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2021 IBM Corporation and others.
+ * Copyright (c) 2000, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -14,10 +14,8 @@
package org.eclipse.swt.internal;
import java.io.*;
-import java.lang.reflect.*;
import java.net.*;
import java.nio.file.*;
-import java.util.function.*;
import java.util.jar.*;
public class Library {
@@ -32,12 +30,12 @@ public class Library {
/**
* SWT Minor version number (must be in the range 0..999)
*/
- static int MINOR_VERSION = 950;
+ static int MINOR_VERSION = 952;
/**
* SWT revision number (must be >= 0)
*/
- static int REVISION = 3;
+ static int REVISION = 6;
/**
* The JAVA and SWT versions
@@ -382,105 +380,4 @@ public static String getVersionString () {
return version;
}
-public static File findResource(String subDir, String resourceName, boolean mapResourceName){
- return findResource(subDir, resourceName, mapResourceName, true, true);
-}
-/**
- * Locates a resource located either in java library path, swt library path, or attempts to extract it from inside swt.jar file.
- * This function supports a single level subfolder, e.g SubFolder/resource.
- *
- * Dev note: (17/12/07) This has been developed and throughly tested on GTK. Designed to work on Cocoa/Win as well, but not tested.
- *
- * @param subDir 'null' or a folder name without slashes. E.g Correct: 'mysubdir', incorrect: '/subdir/'.
- * Platform specific Slashes will be added automatically.
- * @param resourceName e.g swt-webkitgtk
- * @param mapResourceName true if you like platform specific mapping applied to resource name. e.g MyLib -> libMyLib-gtk-4826.so
- */
-public static File findResource(String subDir, String resourceName, boolean mapResourceName, boolean replaceDylib, boolean searchInOsgi){
-
- //We construct a 'maybe' subdirectory path. 'Maybe' because if no subDir given, then it's an empty string "".
- // subdir e.g: subdir
- String maybeSubDirPath = subDir != null ? subDir + SEPARATOR : ""; // e.g: subdir/ or ""
- String maybeSubDirPathWithPrefix = subDir != null ? SEPARATOR + maybeSubDirPath : ""; // e.g: /subdir/ or ""
- final String finalResourceName = mapResourceName ?
- mapLibraryName(resourceName + "-" + Platform.PLATFORM + "-" + getVersionString (), replaceDylib) // e.g libMyLib-gtk-3826.so
- : resourceName;
-
- // 1) Look for the resource in the java/swt library path(s)
- // This code commonly finds the resource if the swt project is a required project and the swt binary (for your platform)
- // project is open in your workplace (found in the JAVA_LIBRARY_PATH) or if you're explicitly specified SWT_LIBRARY_PATH.
- {
- Function<String, File> lookForFileInPath = searchPath -> {
- String classpath = System.getProperty(searchPath);
- if (classpath != null){
- String[] paths = classpath.split(File.pathSeparator);
- for (String path : paths) {
- File file = new File(path + SEPARATOR + maybeSubDirPath + finalResourceName);
- if (file.exists()){
- return file;
- }
- }
- }
- return null;
- };
- File result = null;
- for (String path : new String[] {JAVA_LIB_PATH,SWT_LIB_PATH}) {
- result = lookForFileInPath.apply(path);
- if (result != null)
- return result;
- }
- }
-
- // 2) If SWT is ran as OSGI bundle (e.g inside Eclipse), then local resources are extracted to
- // eclipse/configuration/org.eclipse.osgi/NN/N/.cp/<resource> and we're given a pointer to the file.
- if (searchInOsgi) {
- // If this is an OSGI bundle look for the resource using getResource
- URL url = Library.class.getClassLoader().getResource(maybeSubDirPathWithPrefix + finalResourceName);
- URLConnection connection;
- try {
- connection = url.openConnection();
- Method getFileURLMethod = connection.getClass().getMethod("getFileURL");
- if (getFileURLMethod != null){
- // This method does the actual extraction of file to: ../eclipse/configuration/org.eclipse.osgi/NN/N/.cp/<SubDir>/resource.ext
- URL result = (URL) getFileURLMethod.invoke(connection);
- return new File(result.toURI());
- }
- } catch (Exception e) {
- // If any exceptions are thrown the resource cannot be located this way.
- }
- }
-
- // 3) Need to try to pull the resource out of the swt.jar.
- // Look for the resource in the user's home directory, (if already extracted in the temp swt folder. (~/.swt/lib...)
- // Extract from the swt.jar if not there already.
- {
- // Developer note:
- // To test this piece of code, you need to compile SWT into a jar and use it in a test project. E.g
- // cd ~/git/eclipse.platform.swt.binaries/bundles/org.eclipse.swt.gtk.linux.x86_64/
- // mvn clean verify -Pbuild-individual-bundles -Dnative=gtk.linux.x86_64
- // then ./target/ will contain org.eclipse.swt.gtk.linux.x86_64-3.106.100-SNAPSHOT.jar (and it's source),
- // you can copy those into your test swt project and test that your resource is extracted into something like ~/.swt/...
- // Lastly, if using subDir, you need to edit the build.properties and specify the folder you wish to have included in your jar in the includes.
- File file = new File (USER_HOME + SEPARATOR + SWT_LIB_DIR + maybeSubDirPathWithPrefix, finalResourceName);
- if (file.exists()){
- return file;
- } else { // Try to extract file from jar if not found.
-
- // Create temp directory if it doesn't exist
- File tempDir = new File (USER_HOME, SWT_LIB_DIR + maybeSubDirPathWithPrefix);
- if ((!tempDir.exists () || tempDir.isDirectory ())) {
- tempDir.mkdirs ();
- }
-
- if (extract(file.getPath(), maybeSubDirPath + finalResourceName)) {
- if (file.exists()) {
- return file;
- }
- }
- }
- }
- throw new UnsatisfiedLinkError("Could not find resource " + resourceName + (subDir != null ? " (in subdirectory: " + subDir + " )" : ""));
-}
-
-
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/build.sh b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/build.sh
index 3dea89eb97..d1694a9020 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/build.sh
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/build.sh
@@ -144,11 +144,22 @@ case $SWT_OS.$SWT_ARCH in
export PKG_CONFIG_PATH="/usr/lib64/pkgconfig/"
fi
;;
+ "linux.loongarch64")
+ if [ "${CC}" = "" ]; then
+ export CC=gcc
+ fi
+ if [ "${JAVA_HOME}" = "" ]; then
+ export JAVA_HOME=`readlink -f /usr/bin/java | sed "s:jre/bin/java::"`
+ fi
+ if [ "${PKG_CONFIG_PATH}" = "" ]; then
+ export PKG_CONFIG_PATH="/usr/lib64/pkgconfig/"
+ fi
+ ;;
esac
# For 64-bit CPUs, we have a switch
-if [ ${MODEL} = 'x86_64' -o ${MODEL} = 'ppc64le' -o ${MODEL} = 'aarch64' ]; then
+if [ ${MODEL} = 'x86_64' -o ${MODEL} = 'ppc64le' -o ${MODEL} = 'aarch64' -o ${MODEL} = 'loongarch64' ]; then
SWT_PTR_CFLAGS=-DJNI64
if [ -d /lib64 ]; then
XLIB64=-L/usr/X11R6/lib64
@@ -174,7 +185,7 @@ fi
if [ ${SWT_OS} = 'win32' ]; then
AWT_LIB_EXPR="jawt.dll"
else
- AWT_LIB_EXPR="libjawt.*"
+ AWT_LIB_EXPR="libjawt.so"
fi
if [ -z "${AWT_LIB_PATH}" ]; then
@@ -254,14 +265,6 @@ func_echo_plus "Building SWT/GTK+ for Architectures: $SWT_OS $SWT_ARCH"
func_build_gtk4 () {
export GTK_VERSION=4.0
- # Dictate Webkit2 Extension only if pkg-config flags exist
- pkg-config --exists webkit2gtk-web-extension-4.0
- if [ $? = 0 ]; then
- export BUILD_WEBKIT2EXTENSION="yes";
- else
- func_echo_error "Warning: Cannot compile Webkit2 Extension because 'pkg-config --exists webkit2gtk-web-extension-4.0' check failed. Please install webkitgtk4-devel.ARCH on your system."
- fi
-
func_echo_plus "Building GTK4 bindings:"
${MAKE_TYPE} -f $MAKEFILE all $MAKE_CAIRO $MAKE_AWT "${@}"
RETURN_VALUE=$? #make can return 1 or 2 if it fails. Thus need to cache it in case it's used programmatically somewhere.
@@ -276,14 +279,6 @@ func_build_gtk4 () {
func_build_gtk3 () {
export GTK_VERSION=3.0
- # Dictate Webkit2 Extension only if pkg-config flags exist
- pkg-config --exists webkit2gtk-web-extension-4.0
- if [ $? = 0 ]; then
- export BUILD_WEBKIT2EXTENSION="yes";
- else
- func_echo_error "Warning: Cannot compile Webkit2 Extension because 'pkg-config --exists webkit2gtk-web-extension-4.0' check failed. Please install webkitgtk4-devel.ARCH on your system."
- fi
-
func_echo_plus "Building GTK3 bindings:"
${MAKE_TYPE} -f $MAKEFILE all $MAKE_CAIRO $MAKE_AWT "${@}"
RETURN_VALUE=$? #make can return 1 or 2 if it fails. Thus need to cache it in case it's used programmatically somewhere.
@@ -313,4 +308,4 @@ elif [ "${GTK_VERSION}" = "4.0" ]; then
elif [ "${GTK_VERSION}" = "3.0" -o "${GTK_VERSION}" = "" ]; then
export GTK_VERSION="3.0"
func_build_gtk3 "$@"
-fi \ No newline at end of file
+fi
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
index 0c6ac3e76d..2e23672cf5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2021 IBM Corporation and others.
+ * Copyright (c) 2000, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -465,6 +465,18 @@ JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1event_1controller_1get_1current_1event)
}
#endif
+#ifndef NO_gtk_1event_1controller_1get_1current_1event_1state
+JNIEXPORT jint JNICALL GTK4_NATIVE(gtk_1event_1controller_1get_1current_1event_1state)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jint rc = 0;
+ GTK4_NATIVE_ENTER(env, that, gtk_1event_1controller_1get_1current_1event_1state_FUNC);
+ rc = (jint)gtk_event_controller_get_current_event_state((GtkEventController *)arg0);
+ GTK4_NATIVE_EXIT(env, that, gtk_1event_1controller_1get_1current_1event_1state_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_gtk_1event_1controller_1key_1new
JNIEXPORT jlong JNICALL GTK4_NATIVE(gtk_1event_1controller_1key_1new)
(JNIEnv *env, jclass that)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c
index d6e33bffc7..7047c84989 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2021 IBM Corporation and others.
+ * Copyright (c) 2000, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -60,6 +60,7 @@ char * GTK4_nativeFunctionNames[] = {
"gtk_1entry_1set_1buffer",
"gtk_1event_1controller_1focus_1new",
"gtk_1event_1controller_1get_1current_1event",
+ "gtk_1event_1controller_1get_1current_1event_1state",
"gtk_1event_1controller_1key_1new",
"gtk_1event_1controller_1motion_1new",
"gtk_1event_1controller_1scroll_1new",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
index dfed94f095..23bc1ce531 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/gtk4_stats.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2021 IBM Corporation and others.
+ * Copyright (c) 2000, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -70,6 +70,7 @@ typedef enum {
gtk_1entry_1set_1buffer_FUNC,
gtk_1event_1controller_1focus_1new_FUNC,
gtk_1event_1controller_1get_1current_1event_FUNC,
+ gtk_1event_1controller_1get_1current_1event_1state_FUNC,
gtk_1event_1controller_1key_1new_FUNC,
gtk_1event_1controller_1motion_1new_FUNC,
gtk_1event_1controller_1scroll_1new_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak
index 749a6d0900..65c168f3fa 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/make_linux.mak
@@ -41,7 +41,6 @@ endif
CAIRO_PREFIX = swt-cairo
ATK_PREFIX = swt-atk
WEBKIT_PREFIX = swt-webkit
-WEBKIT_EXTENSION_PREFIX=swt-webkit2extension
GLX_PREFIX = swt-glx
SWT_LIB = lib$(SWT_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
@@ -53,11 +52,6 @@ GLX_LIB = lib$(GLX_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
WEBKIT_LIB = lib$(WEBKIT_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
ALL_SWT_LIBS = $(SWT_LIB) $(AWT_LIB) $(SWTPI_LIB) $(CAIRO_LIB) $(ATK_LIB) $(GLX_LIB) $(WEBKIT_LIB)
-# Webkit extension lib has to be put into a separate folder and is treated differently from the other libraries.
-WEBKIT_EXTENSION_LIB = lib$(WEBKIT_EXTENSION_PREFIX)-$(WS_PREFIX)-$(SWT_VERSION).so
-WEBEXTENSION_BASE_DIR = webkitextensions
-WEBEXTENSION_DIR = $(WEBEXTENSION_BASE_DIR)$(maj_ver)$(min_ver)r$(rev)
-
CAIROCFLAGS = `pkg-config --cflags cairo`
CAIROLIBS = `pkg-config --libs-only-L cairo` -lcairo
@@ -85,9 +79,6 @@ GLXLIBS = -lGL -lGLU -lm
WEBKITLIBS = `pkg-config --libs-only-l gio-2.0`
WEBKITCFLAGS = `pkg-config --cflags gio-2.0`
-WEBKIT_EXTENSION_CFLAGS=`pkg-config --cflags gtk+-3.0 webkit2gtk-web-extension-4.0`
-WEBKIT_EXTENSION_LFLAGS=`pkg-config --libs gtk+-3.0 webkit2gtk-web-extension-4.0`
-
ifdef SWT_WEBKIT_DEBUG
# don't use 'webkit2gtk-4.0' in production, as some systems might not have those libs and we get crashes.
WEBKITLIBS += `pkg-config --libs-only-l webkit2gtk-4.0`
@@ -215,11 +206,7 @@ atk_stats.o: atk_stats.c atk_structs.h atk_stats.h atk.h
#
# WebKit lib
#
-ifeq ($(BUILD_WEBKIT2EXTENSION),yes)
-make_webkit: $(WEBKIT_LIB) make_webkit2extension
-else
make_webkit: $(WEBKIT_LIB)
-endif
$(WEBKIT_LIB): $(WEBKIT_OBJECTS)
$(CC) $(LFLAGS) -o $(WEBKIT_LIB) $(WEBKIT_OBJECTS) $(WEBKITLIBS)
@@ -236,16 +223,6 @@ webkitgtk_stats.o: webkitgtk_stats.c webkitgtk_stats.h
webkitgtk_custom.o: webkitgtk_custom.c
$(CC) $(CFLAGS) $(WEBKITCFLAGS) -c webkitgtk_custom.c
-
-# Webkit2 extension is a seperate .so lib.
-make_webkit2extension: $(WEBKIT_EXTENSION_LIB)
-
-$(WEBKIT_EXTENSION_LIB) : webkitgtk_extension.o
- $(CC) $(LFLAGS) -o $@ $^ $(WEBKIT_EXTENSION_LFLAGS)
-
-webkitgtk_extension.o : webkitgtk_extension.c
- $(CC) $(CFLAGS) $(WEBKIT_EXTENSION_CFLAGS) ${SWT_PTR_CFLAGS} -fPIC -c $^
-
#
# GLX lib
#
@@ -275,16 +252,6 @@ glx_stats.o: glx_stats.c glx_stats.h
# I hope there are no spaces in the path :-).
install: all
cp $(ALL_SWT_LIBS) $(OUTPUT_DIR)
-ifeq ($(BUILD_WEBKIT2EXTENSION),yes)
- @# Copy webextension into it's own folder, but create folder first.
- @# CAREFULLY delete '.so' files inside webextension*. Then carefully remove the directories. 'rm -rf' seemed too risky of an approach.
- @-[ "$$(ls -d $(OUTPUT_DIR)/$(WEBEXTENSION_BASE_DIR)*/*.so)" ] && rm -v `ls -d $(OUTPUT_DIR)/$(WEBEXTENSION_BASE_DIR)*/*.so`
- @-[ "$$(ls -d $(OUTPUT_DIR)/$(WEBEXTENSION_BASE_DIR)*)" ] && rmdir -v `ls -d $(OUTPUT_DIR)/$(WEBEXTENSION_BASE_DIR)*`
-
- @# Copying webextension is not critical for build to succeed, thus we use '-'. SWT can still function without a webextension.
- @-[ -d $(OUTPUT_DIR)/$(WEBEXTENSION_DIR) ] || mkdir -v $(OUTPUT_DIR)/$(WEBEXTENSION_DIR) # If folder does not exist, make it.
- -cp $(WEBKIT_EXTENSION_LIB) $(OUTPUT_DIR)/$(WEBEXTENSION_DIR)/
-endif
#
# Clean
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
index 03523d86ef..cea7169846 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2021 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2022 IBM Corporation and others. All rights reserved.
* The contents of this file are made available under the terms
* of the GNU Lesser General Public License (LGPL) Version 2.1 that
* accompanies this distribution (lgpl-v21.txt). The LGPL is also
@@ -10851,6 +10851,18 @@ JNIEXPORT jlong JNICALL OS_NATIVE(X_1EVENT_1WINDOW)
}
#endif
+#ifndef NO_addressof_1g_1free
+JNIEXPORT jlong JNICALL OS_NATIVE(addressof_1g_1free)
+ (JNIEnv *env, jclass that)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, addressof_1g_1free_FUNC);
+ rc = (jlong)&g_free;
+ OS_NATIVE_EXIT(env, that, addressof_1g_1free_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_call__JJJJJ
JNIEXPORT jlong JNICALL OS_NATIVE(call__JJJJJ)
(JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jlong arg3, jlong arg4)
@@ -11172,34 +11184,6 @@ fail:
}
#endif
-#ifndef NO_g_1credentials_1is_1same_1user
-JNIEXPORT jboolean JNICALL OS_NATIVE(g_1credentials_1is_1same_1user)
- (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2)
-{
- jlong *lparg2=NULL;
- jboolean rc = 0;
- OS_NATIVE_ENTER(env, that, g_1credentials_1is_1same_1user_FUNC);
- if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
- rc = (jboolean)g_credentials_is_same_user((GCredentials *)arg0, (GCredentials *)arg1, (GError **)lparg2);
-fail:
- if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
- OS_NATIVE_EXIT(env, that, g_1credentials_1is_1same_1user_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_g_1credentials_1new
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1credentials_1new)
- (JNIEnv *env, jclass that)
-{
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1credentials_1new_FUNC);
- rc = (jlong)g_credentials_new();
- OS_NATIVE_EXIT(env, that, g_1credentials_1new_FUNC);
- return rc;
-}
-#endif
-
#ifndef NO_g_1date_1time_1get_1ymd
JNIEXPORT void JNICALL OS_NATIVE(g_1date_1time_1get_1ymd)
(JNIEnv *env, jclass that, jlong arg0, jintArray arg1, jintArray arg2, jintArray arg3)
@@ -11242,143 +11226,6 @@ JNIEXPORT void JNICALL OS_NATIVE(g_1date_1time_1unref)
}
#endif
-#ifndef NO_g_1dbus_1auth_1observer_1new
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1dbus_1auth_1observer_1new)
- (JNIEnv *env, jclass that)
-{
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1dbus_1auth_1observer_1new_FUNC);
- rc = (jlong)g_dbus_auth_observer_new();
- OS_NATIVE_EXIT(env, that, g_1dbus_1auth_1observer_1new_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_g_1dbus_1connection_1call
-JNIEXPORT void JNICALL OS_NATIVE(g_1dbus_1connection_1call)
- (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1, jbyteArray arg2, jbyteArray arg3, jbyteArray arg4, jlong arg5, jlong arg6, jint arg7, jint arg8, jlong arg9, jlong arg10, jlong arg11)
-{
- jbyte *lparg1=NULL;
- jbyte *lparg2=NULL;
- jbyte *lparg3=NULL;
- jbyte *lparg4=NULL;
- OS_NATIVE_ENTER(env, that, g_1dbus_1connection_1call_FUNC);
- if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
- if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail;
- if (arg3) if ((lparg3 = (*env)->GetByteArrayElements(env, arg3, NULL)) == NULL) goto fail;
- if (arg4) if ((lparg4 = (*env)->GetByteArrayElements(env, arg4, NULL)) == NULL) goto fail;
- g_dbus_connection_call((GDBusConnection *)arg0, (const gchar *)lparg1, (const gchar *)lparg2, (const gchar *)lparg3, (const gchar *)lparg4, (GVariant *)arg5, (const GVariantType *)arg6, arg7, arg8, (GCancellable *)arg9, (GAsyncReadyCallback)arg10, (gpointer)arg11);
-fail:
- if (arg4 && lparg4) (*env)->ReleaseByteArrayElements(env, arg4, lparg4, 0);
- if (arg3 && lparg3) (*env)->ReleaseByteArrayElements(env, arg3, lparg3, 0);
- if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0);
- if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1connection_1call_FUNC);
-}
-#endif
-
-#ifndef NO_g_1dbus_1connection_1call_1finish
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1dbus_1connection_1call_1finish)
- (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2)
-{
- jlong *lparg2=NULL;
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1dbus_1connection_1call_1finish_FUNC);
- if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
- rc = (jlong)g_dbus_connection_call_finish((GDBusConnection *)arg0, (GAsyncResult *)arg1, (GError **)lparg2);
-fail:
- if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1connection_1call_1finish_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_g_1dbus_1connection_1call_1sync
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1dbus_1connection_1call_1sync)
- (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1, jbyteArray arg2, jbyteArray arg3, jbyteArray arg4, jlong arg5, jlong arg6, jint arg7, jint arg8, jlong arg9, jlongArray arg10)
-{
- jbyte *lparg1=NULL;
- jbyte *lparg2=NULL;
- jbyte *lparg3=NULL;
- jbyte *lparg4=NULL;
- jlong *lparg10=NULL;
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1dbus_1connection_1call_1sync_FUNC);
- if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
- if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail;
- if (arg3) if ((lparg3 = (*env)->GetByteArrayElements(env, arg3, NULL)) == NULL) goto fail;
- if (arg4) if ((lparg4 = (*env)->GetByteArrayElements(env, arg4, NULL)) == NULL) goto fail;
- if (arg10) if ((lparg10 = (*env)->GetLongArrayElements(env, arg10, NULL)) == NULL) goto fail;
- rc = (jlong)g_dbus_connection_call_sync((GDBusConnection *)arg0, (const gchar *)lparg1, (const gchar *)lparg2, (const gchar *)lparg3, (const gchar *)lparg4, (GVariant *)arg5, (const GVariantType *)arg6, arg7, arg8, (GCancellable *)arg9, (GError **)lparg10);
-fail:
- if (arg10 && lparg10) (*env)->ReleaseLongArrayElements(env, arg10, lparg10, 0);
- if (arg4 && lparg4) (*env)->ReleaseByteArrayElements(env, arg4, lparg4, 0);
- if (arg3 && lparg3) (*env)->ReleaseByteArrayElements(env, arg3, lparg3, 0);
- if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0);
- if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1connection_1call_1sync_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_g_1dbus_1connection_1close_1sync
-JNIEXPORT jboolean JNICALL OS_NATIVE(g_1dbus_1connection_1close_1sync)
- (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2)
-{
- jlong *lparg2=NULL;
- jboolean rc = 0;
- OS_NATIVE_ENTER(env, that, g_1dbus_1connection_1close_1sync_FUNC);
- if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
- rc = (jboolean)g_dbus_connection_close_sync((GDBusConnection *)arg0, (GCancellable *)arg1, (GError **)lparg2);
-fail:
- if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1connection_1close_1sync_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_g_1dbus_1connection_1is_1closed
-JNIEXPORT jboolean JNICALL OS_NATIVE(g_1dbus_1connection_1is_1closed)
- (JNIEnv *env, jclass that, jlong arg0)
-{
- jboolean rc = 0;
- OS_NATIVE_ENTER(env, that, g_1dbus_1connection_1is_1closed_FUNC);
- rc = (jboolean)g_dbus_connection_is_closed((GDBusConnection *)arg0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1connection_1is_1closed_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_g_1dbus_1connection_1new_1for_1address
-JNIEXPORT void JNICALL OS_NATIVE(g_1dbus_1connection_1new_1for_1address)
- (JNIEnv *env, jclass that, jbyteArray arg0, jint arg1, jlong arg2, jlong arg3, jlong arg4, jlong arg5)
-{
- jbyte *lparg0=NULL;
- OS_NATIVE_ENTER(env, that, g_1dbus_1connection_1new_1for_1address_FUNC);
- if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
- g_dbus_connection_new_for_address((const gchar *)lparg0, arg1, (GDBusAuthObserver *)arg2, (GCancellable *)arg3, (GAsyncReadyCallback)arg4, (gpointer)arg5);
-fail:
- if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, 0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1connection_1new_1for_1address_FUNC);
-}
-#endif
-
-#ifndef NO_g_1dbus_1connection_1new_1for_1address_1finish
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1dbus_1connection_1new_1for_1address_1finish)
- (JNIEnv *env, jclass that, jlong arg0, jlongArray arg1)
-{
- jlong *lparg1=NULL;
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1dbus_1connection_1new_1for_1address_1finish_FUNC);
- if (arg1) if ((lparg1 = (*env)->GetLongArrayElements(env, arg1, NULL)) == NULL) goto fail;
- rc = (jlong)g_dbus_connection_new_for_address_finish((GAsyncResult *)arg0, (GError **)lparg1);
-fail:
- if (arg1 && lparg1) (*env)->ReleaseLongArrayElements(env, arg1, lparg1, 0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1connection_1new_1for_1address_1finish_FUNC);
- return rc;
-}
-#endif
-
#ifndef NO_g_1dbus_1connection_1register_1object
JNIEXPORT jint JNICALL OS_NATIVE(g_1dbus_1connection_1register_1object)
(JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1, jlong arg2, jlongArray arg3, jlong arg4, jlong arg5, jlongArray arg6)
@@ -11401,18 +11248,6 @@ fail:
}
#endif
-#ifndef NO_g_1dbus_1generate_1guid
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1dbus_1generate_1guid)
- (JNIEnv *env, jclass that)
-{
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1dbus_1generate_1guid_FUNC);
- rc = (jlong)g_dbus_generate_guid();
- OS_NATIVE_EXIT(env, that, g_1dbus_1generate_1guid_FUNC);
- return rc;
-}
-#endif
-
#ifndef NO_g_1dbus_1method_1invocation_1return_1value
JNIEXPORT void JNICALL OS_NATIVE(g_1dbus_1method_1invocation_1return_1value)
(JNIEnv *env, jclass that, jlong arg0, jlong arg1)
@@ -11531,54 +11366,6 @@ fail:
}
#endif
-#ifndef NO_g_1dbus_1server_1get_1client_1address
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1dbus_1server_1get_1client_1address)
- (JNIEnv *env, jclass that, jlong arg0)
-{
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1dbus_1server_1get_1client_1address_FUNC);
- rc = (jlong)g_dbus_server_get_client_address((GDBusServer *)arg0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1server_1get_1client_1address_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_g_1dbus_1server_1new_1sync
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1dbus_1server_1new_1sync)
- (JNIEnv *env, jclass that, jlong arg0, jint arg1, jlong arg2, jlong arg3, jlong arg4, jlongArray arg5)
-{
- jlong *lparg5=NULL;
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1dbus_1server_1new_1sync_FUNC);
- if (arg5) if ((lparg5 = (*env)->GetLongArrayElements(env, arg5, NULL)) == NULL) goto fail;
- rc = (jlong)g_dbus_server_new_sync((const gchar *)arg0, (GDBusServerFlags)arg1, (const gchar *)arg2, (GDBusAuthObserver *)arg3, (GCancellable *)arg4, (GError **)lparg5);
-fail:
- if (arg5 && lparg5) (*env)->ReleaseLongArrayElements(env, arg5, lparg5, 0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1server_1new_1sync_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_g_1dbus_1server_1start
-JNIEXPORT void JNICALL OS_NATIVE(g_1dbus_1server_1start)
- (JNIEnv *env, jclass that, jlong arg0)
-{
- OS_NATIVE_ENTER(env, that, g_1dbus_1server_1start_FUNC);
- g_dbus_server_start((GDBusServer *)arg0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1server_1start_FUNC);
-}
-#endif
-
-#ifndef NO_g_1dbus_1server_1stop
-JNIEXPORT void JNICALL OS_NATIVE(g_1dbus_1server_1stop)
- (JNIEnv *env, jclass that, jlong arg0)
-{
- OS_NATIVE_ENTER(env, that, g_1dbus_1server_1stop_FUNC);
- g_dbus_server_stop((GDBusServer *)arg0);
- OS_NATIVE_EXIT(env, that, g_1dbus_1server_1stop_FUNC);
-}
-#endif
-
#ifndef NO_g_1dir_1make_1tmp
JNIEXPORT jlong JNICALL OS_NATIVE(g_1dir_1make_1tmp)
(JNIEnv *env, jclass that, jlong arg0, jlongArray arg1)
@@ -11617,6 +11404,30 @@ JNIEXPORT jlong JNICALL OS_NATIVE(g_1error_1get_1message)
}
#endif
+#ifndef NO_g_1error_1matches
+JNIEXPORT jboolean JNICALL OS_NATIVE(g_1error_1matches)
+ (JNIEnv *env, jclass that, jlong arg0, jint arg1, jint arg2)
+{
+ jboolean rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1error_1matches_FUNC);
+ rc = (jboolean)g_error_matches((const GError *)arg0, (GQuark)arg1, (gint)arg2);
+ OS_NATIVE_EXIT(env, that, g_1error_1matches_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_g_1file_1error_1quark
+JNIEXPORT jint JNICALL OS_NATIVE(g_1file_1error_1quark)
+ (JNIEnv *env, jclass that)
+{
+ jint rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1file_1error_1quark_FUNC);
+ rc = (jint)g_file_error_quark();
+ OS_NATIVE_EXIT(env, that, g_1file_1error_1quark_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_g_1file_1get_1path
JNIEXPORT jlong JNICALL OS_NATIVE(g_1file_1get_1path)
(JNIEnv *env, jclass that, jlong arg0)
@@ -11846,18 +11657,6 @@ JNIEXPORT void JNICALL OS_NATIVE(g_1get_1current_1time)
G_GNUC_END_IGNORE_DEPRECATIONS
#endif
-#ifndef NO_g_1get_1user_1name
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1get_1user_1name)
- (JNIEnv *env, jclass that)
-{
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1get_1user_1name_FUNC);
- rc = (jlong)g_get_user_name();
- OS_NATIVE_EXIT(env, that, g_1get_1user_1name_FUNC);
- return rc;
-}
-#endif
-
#ifndef NO_g_1getenv
JNIEXPORT jlong JNICALL OS_NATIVE(g_1getenv)
(JNIEnv *env, jclass that, jbyteArray arg0)
@@ -12199,6 +11998,18 @@ JNIEXPORT jlong JNICALL OS_NATIVE(g_1malloc)
}
#endif
+#ifndef NO_g_1memory_1input_1stream_1new_1from_1data
+JNIEXPORT jlong JNICALL OS_NATIVE(g_1memory_1input_1stream_1new_1from_1data)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2)
+{
+ jlong rc = 0;
+ OS_NATIVE_ENTER(env, that, g_1memory_1input_1stream_1new_1from_1data_FUNC);
+ rc = (jlong)g_memory_input_stream_new_from_data((const void *)arg0, (gssize)arg1, (GDestroyNotify)arg2);
+ OS_NATIVE_EXIT(env, that, g_1memory_1input_1stream_1new_1from_1data_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_g_1menu_1insert_1item
JNIEXPORT void JNICALL OS_NATIVE(g_1menu_1insert_1item)
(JNIEnv *env, jclass that, jlong arg0, jint arg1, jlong arg2)
@@ -12899,30 +12710,6 @@ JNIEXPORT jboolean JNICALL OS_NATIVE(g_1source_1remove)
}
#endif
-#ifndef NO_g_1strconcat__JJJ
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1strconcat__JJJ)
- (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2)
-{
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1strconcat__JJJ_FUNC);
- rc = (jlong)g_strconcat((const gchar *)arg0, (const gchar *)arg1, (const gchar *)NULL);
- OS_NATIVE_EXIT(env, that, g_1strconcat__JJJ_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_g_1strconcat__JJJJ
-JNIEXPORT jlong JNICALL OS_NATIVE(g_1strconcat__JJJJ)
- (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jlong arg3)
-{
- jlong rc = 0;
- OS_NATIVE_ENTER(env, that, g_1strconcat__JJJJ_FUNC);
- rc = (jlong)g_strconcat((const gchar *)arg0, (const gchar *)arg1, (const gchar *)arg2, (const gchar *)NULL);
- OS_NATIVE_EXIT(env, that, g_1strconcat__JJJJ_FUNC);
- return rc;
-}
-#endif
-
#ifndef NO_g_1strdup
JNIEXPORT jlong JNICALL OS_NATIVE(g_1strdup)
(JNIEnv *env, jclass that, jlong arg0)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
index b289ad04d2..0ab5dc85d2 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2021 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2022 IBM Corporation and others. All rights reserved.
* The contents of this file are made available under the terms
* of the GNU Lesser General Public License (LGPL) Version 2.1 that
* accompanies this distribution (lgpl-v21.txt). The LGPL is also
@@ -936,6 +936,7 @@ char * OS_nativeFunctionNames[] = {
"XSynchronize",
"X_1EVENT_1TYPE",
"X_1EVENT_1WINDOW",
+ "addressof_1g_1free",
"call__JJJJJ",
"call__JJJJJJJ",
"call__JJJJJJJJ",
@@ -961,21 +962,10 @@ char * OS_nativeFunctionNames[] = {
"g_1closure_1unref",
"g_1content_1type_1equals",
"g_1content_1type_1is_1a",
- "g_1credentials_1is_1same_1user",
- "g_1credentials_1new",
"g_1date_1time_1get_1ymd",
"g_1date_1time_1new_1local",
"g_1date_1time_1unref",
- "g_1dbus_1auth_1observer_1new",
- "g_1dbus_1connection_1call",
- "g_1dbus_1connection_1call_1finish",
- "g_1dbus_1connection_1call_1sync",
- "g_1dbus_1connection_1close_1sync",
- "g_1dbus_1connection_1is_1closed",
- "g_1dbus_1connection_1new_1for_1address",
- "g_1dbus_1connection_1new_1for_1address_1finish",
"g_1dbus_1connection_1register_1object",
- "g_1dbus_1generate_1guid",
"g_1dbus_1method_1invocation_1return_1value",
"g_1dbus_1node_1info_1lookup_1interface",
"g_1dbus_1node_1info_1new_1for_1xml",
@@ -983,13 +973,11 @@ char * OS_nativeFunctionNames[] = {
"g_1dbus_1proxy_1call_1sync",
"g_1dbus_1proxy_1get_1name_1owner",
"g_1dbus_1proxy_1new_1for_1bus_1sync",
- "g_1dbus_1server_1get_1client_1address",
- "g_1dbus_1server_1new_1sync",
- "g_1dbus_1server_1start",
- "g_1dbus_1server_1stop",
"g_1dir_1make_1tmp",
"g_1error_1free",
"g_1error_1get_1message",
+ "g_1error_1matches",
+ "g_1file_1error_1quark",
"g_1file_1get_1path",
"g_1file_1get_1uri",
"g_1file_1info_1get_1content_1type",
@@ -1005,7 +993,6 @@ char * OS_nativeFunctionNames[] = {
"g_1filename_1to_1utf8",
"g_1free",
"g_1get_1current_1time",
- "g_1get_1user_1name",
"g_1getenv",
"g_1icon_1new_1for_1string",
"g_1icon_1to_1string",
@@ -1033,6 +1020,7 @@ char * OS_nativeFunctionNames[] = {
"g_1main_1context_1release",
"g_1main_1context_1wakeup",
"g_1malloc",
+ "g_1memory_1input_1stream_1new_1from_1data",
"g_1menu_1insert_1item",
"g_1menu_1item_1new",
"g_1menu_1item_1new_1section",
@@ -1085,8 +1073,6 @@ char * OS_nativeFunctionNames[] = {
"g_1slist_1length",
"g_1slist_1next",
"g_1source_1remove",
- "g_1strconcat__JJJ",
- "g_1strconcat__JJJJ",
"g_1strdup",
"g_1strfreev",
"g_1strtod",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
index 4a96c27687..057048bff8 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2021 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2022 IBM Corporation and others. All rights reserved.
* The contents of this file are made available under the terms
* of the GNU Lesser General Public License (LGPL) Version 2.1 that
* accompanies this distribution (lgpl-v21.txt). The LGPL is also
@@ -910,6 +910,7 @@ typedef enum {
XSynchronize_FUNC,
X_1EVENT_1TYPE_FUNC,
X_1EVENT_1WINDOW_FUNC,
+ addressof_1g_1free_FUNC,
call__JJJJJ_FUNC,
call__JJJJJJJ_FUNC,
call__JJJJJJJJ_FUNC,
@@ -935,21 +936,10 @@ typedef enum {
g_1closure_1unref_FUNC,
g_1content_1type_1equals_FUNC,
g_1content_1type_1is_1a_FUNC,
- g_1credentials_1is_1same_1user_FUNC,
- g_1credentials_1new_FUNC,
g_1date_1time_1get_1ymd_FUNC,
g_1date_1time_1new_1local_FUNC,
g_1date_1time_1unref_FUNC,
- g_1dbus_1auth_1observer_1new_FUNC,
- g_1dbus_1connection_1call_FUNC,
- g_1dbus_1connection_1call_1finish_FUNC,
- g_1dbus_1connection_1call_1sync_FUNC,
- g_1dbus_1connection_1close_1sync_FUNC,
- g_1dbus_1connection_1is_1closed_FUNC,
- g_1dbus_1connection_1new_1for_1address_FUNC,
- g_1dbus_1connection_1new_1for_1address_1finish_FUNC,
g_1dbus_1connection_1register_1object_FUNC,
- g_1dbus_1generate_1guid_FUNC,
g_1dbus_1method_1invocation_1return_1value_FUNC,
g_1dbus_1node_1info_1lookup_1interface_FUNC,
g_1dbus_1node_1info_1new_1for_1xml_FUNC,
@@ -957,13 +947,11 @@ typedef enum {
g_1dbus_1proxy_1call_1sync_FUNC,
g_1dbus_1proxy_1get_1name_1owner_FUNC,
g_1dbus_1proxy_1new_1for_1bus_1sync_FUNC,
- g_1dbus_1server_1get_1client_1address_FUNC,
- g_1dbus_1server_1new_1sync_FUNC,
- g_1dbus_1server_1start_FUNC,
- g_1dbus_1server_1stop_FUNC,
g_1dir_1make_1tmp_FUNC,
g_1error_1free_FUNC,
g_1error_1get_1message_FUNC,
+ g_1error_1matches_FUNC,
+ g_1file_1error_1quark_FUNC,
g_1file_1get_1path_FUNC,
g_1file_1get_1uri_FUNC,
g_1file_1info_1get_1content_1type_FUNC,
@@ -979,7 +967,6 @@ typedef enum {
g_1filename_1to_1utf8_FUNC,
g_1free_FUNC,
g_1get_1current_1time_FUNC,
- g_1get_1user_1name_FUNC,
g_1getenv_FUNC,
g_1icon_1new_1for_1string_FUNC,
g_1icon_1to_1string_FUNC,
@@ -1007,6 +994,7 @@ typedef enum {
g_1main_1context_1release_FUNC,
g_1main_1context_1wakeup_FUNC,
g_1malloc_FUNC,
+ g_1memory_1input_1stream_1new_1from_1data_FUNC,
g_1menu_1insert_1item_FUNC,
g_1menu_1item_1new_FUNC,
g_1menu_1item_1new_1section_FUNC,
@@ -1059,8 +1047,6 @@ typedef enum {
g_1slist_1length_FUNC,
g_1slist_1next_FUNC,
g_1source_1remove_FUNC,
- g_1strconcat__JJJ_FUNC,
- g_1strconcat__JJJJ_FUNC,
g_1strdup_FUNC,
g_1strfreev_FUNC,
g_1strtod_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkRectangle.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkRectangle.java
index 4e547d07e8..7623e32142 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkRectangle.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkRectangle.java
@@ -14,6 +14,7 @@
*******************************************************************************/
package org.eclipse.swt.internal.gtk;
+import org.eclipse.swt.graphics.Rectangle;
public class GdkRectangle {
/** @field cast=(gint) */
@@ -36,4 +37,8 @@ public class GdkRectangle {
public String toString() {
return "GdkRectangle {" + x + ", " + y + ", " + width + ", " + height + "}"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
}
+
+ public Rectangle toRectangle() {
+ return new Rectangle(x, y, width, height);
+ }
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
index c1850b9764..64d9ac9fba 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2021 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2000, 2022 IBM Corporation and others. All rights reserved.
* The contents of this file are made available under the terms
* of the GNU Lesser General Public License (LGPL) Version 2.1 that
* accompanies this distribution (lgpl-v21.txt). The LGPL is also
@@ -145,6 +145,7 @@ public class OS extends C {
}
/** Constants */
+ public static final int G_FILE_ERROR_IO = 21;
public static final int G_FILE_TEST_IS_DIR = 1 << 2;
public static final int G_FILE_TEST_IS_EXECUTABLE = 1 << 3;
public static final int G_SIGNAL_MATCH_DATA = 1 << 4;
@@ -210,11 +211,6 @@ public class OS extends C {
public static final int G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START = 3;
public static final int G_DBUS_CALL_FLAGS_NONE = 0;
- public static final int G_DBUS_CALL_FLAGS_NO_AUTO_START = (1<<0);
-
- public static final int G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT = 1;
-
- public static final int G_DBUS_SERVER_FLAGS_NONE = 0;
/**
* DBus Data types as defined by:
@@ -273,7 +269,6 @@ public class OS extends C {
public static final byte[] accel_closures_changed = ascii("accel-closures-changed"); // Gtk3,4
public static final byte[] activate = ascii("activate"); // ?
public static final byte[] angle_changed = ascii("angle_changed"); // Gtk3/4, Guesture related.
- public static final byte[] authorize_authenticated_peer = ascii("authorize-authenticated-peer");
public static final byte[] backspace = ascii("backspace");
public static final byte[] begin = ascii("begin");
public static final byte[] button_press_event = ascii("button-press-event");
@@ -339,7 +334,6 @@ public class OS extends C {
public static final byte[] motion = ascii("motion");
public static final byte[] move_cursor = ascii("move-cursor");
public static final byte[] move_focus = ascii("move-focus");
- public static final byte[] new_connection = ascii("new-connection");
public static final byte[] output = ascii("output");
public static final byte[] paste_clipboard = ascii("paste-clipboard");
public static final byte[] pressed = ascii("pressed");
@@ -376,6 +370,7 @@ public class OS extends C {
public static final byte[] notify_default_height = ascii("notify::default-height");
public static final byte[] notify_default_width = ascii("notify::default-width");
public static final byte[] notify_maximized = ascii("notify::maximized");
+ public static final byte[] notify_is_active = ascii("notify::is-active");
public static final byte[] notify_theme_change = ascii("notify::gtk-application-prefer-dark-theme");
public static final byte[] response = ascii("response");
public static final byte[] compute_size = ascii("compute-size");
@@ -899,6 +894,12 @@ public static final native boolean g_app_info_supports_uris(long appInfo);
* @param error cast=(GError *)
*/
public static final native long g_error_get_message(long error);
+/**
+ * @param error cast=(const GError *)
+ * @param domain cast=(GQuark)
+ * @param code cast=(gint)
+ */
+public static final native boolean g_error_matches(long error, int domain, int code);
/**
* @param gerror cast=(GError *)
@@ -915,13 +916,7 @@ public static final native boolean g_content_type_equals(long type1, byte[] type
* @param supertype cast=(gchar *)
*/
public static final native boolean g_content_type_is_a(long type, byte[] supertype);
-public static final native long g_credentials_new();
-/**
- * @param credentials cast=(GCredentials *)
- * @param other_credentials cast=(GCredentials *)
- * @param error cast=(GError **)
- */
-public static final native boolean g_credentials_is_same_user(long credentials, long other_credentials, long [] error);
+public static final native int g_file_error_quark();
/**
* @param info cast=(GFileInfo *)
*/
@@ -1042,6 +1037,8 @@ public static final native long g_filename_from_utf8(long opsysstring, long len,
public static final native long g_filename_from_uri(long uri, long [] hostname, long [] error);
/** @param mem cast=(gpointer) */
public static final native void g_free(long mem);
+/** @method accessor=g_free,flags=const address */
+public static final native long addressof_g_free();
/**
* @param variable cast=(const gchar *),flags=no_out
*/
@@ -1051,7 +1048,6 @@ public static final native long g_getenv(byte [] variable);
* @param result cast=(GTimeVal *)
*/
public static final native void g_get_current_time(long result);
-public static final native long g_get_user_name();
/**
* @method flags=ignore_deprecations
* @param result cast=(GTimeVal *)
@@ -1300,19 +1296,6 @@ public static final native void g_strfreev(long string_array);
* @param endptr cast=(gchar **)
*/
public static final native double g_strtod(long str, long [] endptr);
-/**
- * @param str cast=(const gchar *)
- * @param str2 cast=(const gchar *)
- * @param str3 cast=(const gchar *)
- * @param terminator cast=(const gchar *),flags=sentinel
- */
-public static final native long g_strconcat(long str, long str2, long str3, long terminator);
-/**
- * @param str cast=(const gchar *)
- * @param str2 cast=(const gchar *)
- * @param terminator cast=(const gchar *),flags=sentinel
- */
-public static final native long g_strconcat(long str, long str2, long terminator);
/** @param str cast=(char *) */
public static final native long g_strdup (long str);
/** @param g_class cast=(GType) */
@@ -1880,6 +1863,27 @@ public static final byte [] getThemeNameBytes() {
}
/**
+ * Experimental API for dark theme.
+ * <p>
+ * On Windows, there is no OS API for dark theme yet, and this method only
+ * configures various tweaks. Some of these tweaks have drawbacks. The tweaks
+ * are configured with defaults that fit Eclipse. Non-Eclipse applications are
+ * expected to configure individual tweaks instead of calling this method.
+ * Please see <code>Display#setData()</code> and documentation for string keys
+ * used there.
+ * </p>
+ * <p>
+ * On GTK, behavior may be different as the boolean flag doesn't force dark
+ * theme instead it specify that dark theme is preferred.
+ * </p>
+ *
+ * @param isDarkTheme <code>true</code> for dark theme
+ */
+public static final void setTheme(boolean isDarkTheme) {
+ setDarkThemePreferred (isDarkTheme);
+}
+
+/**
* @param tmpl cast=(const gchar *)
* @param error cast=(GError **)
*/
@@ -1946,74 +1950,6 @@ public static final native int g_bus_own_name(int bus_type, byte[] name, int fla
/**
* @param connection cast=(GDBusConnection *)
- * @param bus_name cast=(const gchar *)
- * @param object_path cast=(const gchar *)
- * @param interface_name cast=(const gchar *)
- * @param method_name cast=(const gchar *)
- * @param param cast=(GVariant *)
- * @param reply_type cast=(const GVariantType *)
- * @param cancellable cast=(GCancellable *)
- * @param callback cast=(GAsyncReadyCallback)
- * @param user_data cast=(gpointer)
- * @category gdbus
- */
-public static final native void g_dbus_connection_call(long connection, byte [] bus_name, byte [] object_path, byte [] interface_name, byte [] method_name, long param, long reply_type, int flag, int timeout, long cancellable, long callback, long user_data);
-
-/**
- * @param proxy cast=(GDBusConnection *)
- * @param res cast=(GAsyncResult *)
- * @param error cast=(GError **)
- * @category gdbus
- */
-public static final native long g_dbus_connection_call_finish(long proxy, long res, long [] error);
-
-/**
- * @param connection cast=(GDBusConnection *)
- * @param bus_name cast=(const gchar *)
- * @param object_path cast=(const gchar *)
- * @param interface_name cast=(const gchar *)
- * @param method_name cast=(const gchar *)
- * @param param cast=(GVariant *)
- * @param reply_type cast=(const GVariantType *)
- * @param cancellable cast=(GCancellable *)
- * @param error cast=(GError **)
- * @category gdbus
- */
-public static final native long g_dbus_connection_call_sync(long connection, byte [] bus_name, byte [] object_path, byte [] interface_name, byte [] method_name, long param, long reply_type, int flag, int timeout, long cancellable, long [] error);
-
-/**
- * @param connection cast=(GDBusConnection *)
- * @param cancellable cast=(GCancellable *)
- * @param error cast=(GError **)
- * @category gdbus
- */
-public static final native boolean g_dbus_connection_close_sync(long connection, long cancellable, long [] error);
-
-/**
- * @param connection cast=(GDBusConnection *)
- * @category gdbus
- */
-public static final native boolean g_dbus_connection_is_closed(long connection);
-
-/**
- * @param address cast=(const gchar *)
- * @param observer cast=(GDBusAuthObserver *)
- * @param cancellable cast=(GCancellable *)
- * @param callback cast=(GAsyncReadyCallback)
- * @param user_data cast=(gpointer)
- * @category gdbus
- */
-public static final native void g_dbus_connection_new_for_address(byte[] address, int flags, long observer, long cancellable, long callback, long user_data);
-
-/**
- * @param result cast=(GAsyncResult *)
- * @param error cast=(GError **)
- * @category gdbus
- */
-public static final native long g_dbus_connection_new_for_address_finish(long result, long [] error);
-
-/**
- * @param connection cast=(GDBusConnection *)
* @param object_path cast=(const gchar *)
* @param interface_info cast=(GDBusInterfaceInfo *)
* @param vtable cast=(const GDBusInterfaceVTable *)
@@ -2039,45 +1975,6 @@ public static final native long g_dbus_node_info_lookup_interface(long info, byt
public static final native void g_dbus_method_invocation_return_value(long invocation, long parameters);
/**
- * @param address cast=(const gchar *)
- * @param flags cast=(GDBusServerFlags)
- * @param guid cast=(const gchar *)
- * @param observer cast=(GDBusAuthObserver *)
- * @param cancellable cast=(GCancellable *)
- * @param error cast=(GError **)
- * @category gdbus
- */
-public static final native long g_dbus_server_new_sync(long address, int flags, long guid, long observer, long cancellable, long [] error);
-
-/**
- * @param server cast=(GDBusServer *)
- * @category gdbus
- */
-public static final native void g_dbus_server_start(long server);
-
-/**
- * @param server cast=(GDBusServer *)
- * @category gdbus
- */
-public static final native void g_dbus_server_stop(long server);
-
-/**
- * @param server cast=(GDBusServer *)
- * @category gdbus
- */
-public static final native long g_dbus_server_get_client_address(long server);
-
-/**
- * @category gdbus
- */
-public static final native long g_dbus_auth_observer_new();
-
-/**
- * @category gdbus
- */
-public static final native long g_dbus_generate_guid();
-
-/**
* @param type cast=(const GVariantType *)
* @category gdbus
*/
@@ -2382,4 +2279,13 @@ public static final native int g_list_model_get_n_items(long list);
* @param position cast=(guint)
*/
public static final native long g_list_model_get_item(long list, int position);
+
+/* GMemoryInputStream */
+/**
+ * @param data cast=(const void *)
+ * @param len cast=(gssize)
+ * @param destroy cast=(GDestroyNotify)
+ */
+public static final native long g_memory_input_stream_new_from_data(long data, long len, long destroy);
+
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
index cb925a9748..ecff340801 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk4/GTK4.java
@@ -355,6 +355,8 @@ public class GTK4 {
public static final native long gtk_event_controller_focus_new();
/** @param controller cast=(GtkEventController *) */
public static final native long gtk_event_controller_get_current_event(long controller);
+ /** @param controller cast=(GtkEventController *) */
+ public static final native int gtk_event_controller_get_current_event_state(long controller);
public static final native long gtk_event_controller_key_new();
public static final native long gtk_event_controller_motion_new();
/** @param flag cast=(GtkEventControllerScrollFlags) */
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/build.bat b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/build.bat
index c71d94bf4e..41e5f87770 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/build.bat
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/build.bat
@@ -24,47 +24,58 @@ IF "x.%SWT_BUILDDIR%"=="x." set "SWT_BUILDDIR=W:"
echo SWT build dir: %SWT_BUILDDIR%
@rem Specify VisualStudio Edition: 'Community', 'Enterprise', 'Professional' etc.
-IF "x.%MSVC_EDITION%"=="x." set "MSVC_EDITION=Community"
+IF "x.%MSVC_EDITION%"=="x." set "MSVC_EDITION=auto"
-@rem Specify VisualStudio Version: '2017' or newer '2019'
-IF "x.%MSVC_VERSION%"=="x." set "MSVC_VERSION=2019"
+@rem Specify VisualStudio Version: '2022', '2019', '2017' etc.
+IF "x.%MSVC_VERSION%"=="x." set "MSVC_VERSION=auto"
-IF "x.%MSVC_HOME%"=="x." set "MSVC_HOME=%SWT_BUILDDIR%\Microsoft\Visual Studio\%MSVC_VERSION%\"
-IF NOT EXIST "%MSVC_HOME%" set "MSVC_HOME=%ProgramFiles(x86)%\Microsoft Visual Studio\%MSVC_VERSION%\BuildTools"
-IF NOT EXIST "%MSVC_HOME%" set "MSVC_HOME=%ProgramFiles(x86)%\Microsoft Visual Studio\%MSVC_VERSION%\%MSVC_EDITION%"
-IF EXIST "%MSVC_HOME%" (
- echo "Microsoft Visual Studio %MSVC_VERSION% dir: %MSVC_HOME%"
+@rem Search for a usable Visual Studio
+@rem ---------------------------------
+IF "%MSVC_HOME%"=="" CALL :ECHO "'MSVC_HOME' was not provided, auto-searching for Visual Studio..."
+@rem Bug 572308: Path used on older SWT build machines
+IF "%MSVC_HOME%"=="" CALL :FindVisualStudio "%SWT_BUILDDIR%\Microsoft\Visual Studio\$MSVC_VERSION$"
+@rem Bug 574007: Path used on Azure build machines
+IF "%MSVC_HOME%"=="" CALL :FindVisualStudio "%ProgramFiles(x86)%\Microsoft Visual Studio\$MSVC_VERSION$\BuildTools"
+@rem Bug 578519: Common installation paths; VisualStudio is installed in x64 ProgramFiles since VS2022
+IF "%MSVC_HOME%"=="" CALL :FindVisualStudio "%ProgramFiles%\Microsoft Visual Studio\$MSVC_VERSION$\$MSVC_EDITION$"
+@rem Bug 578519: Common installation paths; VisualStudio is installed in x86 ProgramFiles before VS2022
+IF "%MSVC_HOME%"=="" CALL :FindVisualStudio "%ProgramFiles(x86)%\Microsoft Visual Studio\$MSVC_VERSION$\$MSVC_EDITION$"
+@rem Report
+IF NOT EXIST "%MSVC_HOME%" (
+ CALL :ECHO "WARNING: Microsoft Visual Studio was not found (for edition=%MSVC_EDITION% version=%MSVC_VERSION%)"
+ CALL :ECHO " Refer steps for SWT Windows native setup: https://www.eclipse.org/swt/swt_win_native.php"
) ELSE (
- echo "WARNING: Microsoft Visual Studio %MSVC_VERSION% was not found."
- echo " Refer steps for SWT Windows native setup: https://www.eclipse.org/swt/swt_win_native.php"
+ CALL :ECHO "MSVC_HOME: %MSVC_HOME%"
)
-IF NOT "x.%1"=="x.x86_64" (
- ECHO 32-bit builds are no longer supported.
- EXIT /B 1
-)
-
-set PROCESSOR_ARCHITECTURE=AMD64
-IF "x.%OUTPUT_DIR%"=="x." set OUTPUT_DIR=..\..\..\org.eclipse.swt.win32.win32.x86_64
-
-:: Search for a usable JDK
-:: -----------------------
-IF "%SWT_JAVA_HOME%"=="" ECHO 'SWT_JAVA_HOME' was not provided, auto-searching for JDK...
-:: Bug 572733: JDK path used on Azure build machines
+@rem Search for a usable JDK
+@rem -----------------------
+IF "%SWT_JAVA_HOME%"=="" CALL :ECHO "'SWT_JAVA_HOME' was not provided, auto-searching for JDK..."
+@rem Bug 572733: JDK path used on Azure build machines
IF "%SWT_JAVA_HOME%"=="" CALL :TryToUseJdk "%ProgramFiles%\AdoptOpenJDK\jdk-8.0.292.10-hotspot"
-:: Bug 526802: Probably some kind of legacy build machine path
+@rem Bug 526802: Probably some kind of legacy build machine path
IF "%SWT_JAVA_HOME%"=="" CALL :TryToUseJdk "%SWT_BUILDDIR%\Java\Oracle\jdk1.8.0-latest\x64"
-:: Search for generic JDKs so that user can build with little configuration
-:: Note that first found JDK wins, so sort them by order of preference.
+@rem Search for generic JDKs so that user can build with little configuration
+@rem Note that first found JDK wins, so sort them by order of preference.
IF "%SWT_JAVA_HOME%"=="" CALL :TryToUseJdk "%ProgramFiles%\Java\jdk*"
IF "%SWT_JAVA_HOME%"=="" CALL :TryToUseJdk "%ProgramFiles%\AdoptOpenJDK\jdk*"
+@rem Report
IF NOT EXIST "%SWT_JAVA_HOME%" (
- echo "WARNING: x64 Java JDK not found. Please set SWT_JAVA_HOME to your JDK directory."
- echo " Refer steps for SWT Windows native setup: https://www.eclipse.org/swt/swt_win_native.php"
+ CALL :ECHO "WARNING: x64 Java JDK not found. Please set SWT_JAVA_HOME to your JDK directory."
+ CALL :ECHO " Refer steps for SWT Windows native setup: https://www.eclipse.org/swt/swt_win_native.php"
) ELSE (
- echo "SWT_JAVA_HOME x64: %SWT_JAVA_HOME%"
+ CALL :ECHO "SWT_JAVA_HOME x64: %SWT_JAVA_HOME%"
+)
+
+@rem -----------------------
+IF NOT "x.%1"=="x.x86_64" (
+ CALL :ECHO "ERROR: 32-bit builds are no longer supported."
+ EXIT /B 1
)
+set PROCESSOR_ARCHITECTURE=AMD64
+IF "x.%OUTPUT_DIR%"=="x." set OUTPUT_DIR=..\..\..\org.eclipse.swt.win32.win32.x86_64
+
set CFLAGS=-DJNI64
call "%MSVC_HOME%\VC\Auxiliary\Build\vcvarsall.bat" x64
shift
@@ -72,28 +83,103 @@ shift
@rem if call to vcvarsall.bat (which sets up environment) silently fails, then provide advice to user.
WHERE cl
if %ERRORLEVEL% NEQ 0 (
- echo "WARNING: cl (Microsoft C compiler) not found on path. Please install Microsoft Visual Studio."
- echo " If already installed, try launching eclipse from the 'Developer Command Prompt for VS' "
- echo " Refer steps for SWT Windows native setup: https://www.eclipse.org/swt/swt_win_native.php"
+ CALL :ECHO "WARNING: cl (Microsoft C compiler) not found on path. Please install Microsoft Visual Studio."
+ CALL :ECHO " If already installed, try launching eclipse from the 'Developer Command Prompt for VS'"
+ CALL :ECHO " Refer steps for SWT Windows native setup: https://www.eclipse.org/swt/swt_win_native.php"
)
nmake -f make_win32.mak %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
-:TryToUseJdk
-SET TESTED_JDK_PATH_MASK=%~1
-:: Loop over all directories matching mask.
-:: Note that directories are iterated in alphabetical order and *last* hit will
-:: be selected in hopes to select the highest available JDK version.
-FOR /D %%I IN ("%TESTED_JDK_PATH_MASK%") DO (
- IF NOT EXIST "%%~I" (
- ECHO -- JDK '%%~I' doesn't exist on disk
- GOTO :EOF
+@rem Find Visual Studio
+@rem %1 = path template with '$MSVC_VERSION$' and '$MSVC_EDITION$' tokens
+:FindVisualStudio
+ @rem Early return if already found
+ IF NOT "%MSVC_HOME%"=="" GOTO :EOF
+
+ IF "%MSVC_VERSION%"=="auto" (
+ CALL :FindVisualStudio2 "%~1" "2022"
+ CALL :FindVisualStudio2 "%~1" "2019"
+ CALL :FindVisualStudio2 "%~1" "2017"
+ ) ELSE (
+ CALL :FindVisualStudio2 "%~1" "%MSVC_VERSION%"
)
- IF NOT EXIST "%%~I\include\jni.h" (
- ECHO -- JDK '%%~I' is bad: no jni.h
+GOTO :EOF
+
+@rem Find Visual Studio
+@rem %1 = path template with '$MSVC_VERSION$' and '$MSVC_EDITION$' tokens
+@rem %2 = value for '$MSVC_VERSION$'
+:FindVisualStudio2
+ @rem Early return if already found
+ IF NOT "%MSVC_HOME%"=="" GOTO :EOF
+
+ IF "%MSVC_EDITION%"=="auto" (
+ CALL :FindVisualStudio3 "%~1" "%~2" "Community"
+ CALL :FindVisualStudio3 "%~1" "%~2" "Enterprise"
+ CALL :FindVisualStudio3 "%~1" "%~2" "Professional"
+ ) ELSE (
+ CALL :FindVisualStudio3 "%~1" "%~2" "%MSVC_EDITION%"
+ )
+GOTO :EOF
+
+@rem Find Visual Studio
+@rem %1 = path template with '$MSVC_VERSION$' and '$MSVC_EDITION$' tokens
+@rem %2 = value for '$MSVC_VERSION$'
+@rem %3 = value for '$MSVC_EDITION$'
+:FindVisualStudio3
+ @rem Early return if already found
+ IF NOT "%MSVC_HOME%"=="" GOTO :EOF
+
+ SET "TESTED_VS_PATH=%~1"
+ @rem Substitute '$MSVC_VERSION$' and '$MSVC_EDITION$'
+ CALL SET "TESTED_VS_PATH=%%TESTED_VS_PATH:$MSVC_VERSION$=%~2%%"
+ CALL SET "TESTED_VS_PATH=%%TESTED_VS_PATH:$MSVC_EDITION$=%~3%%"
+
+ @rem If the folder isn't there, then skip it without printing errors
+ IF NOT EXIST "%TESTED_VS_PATH%" GOTO :EOF
+
+ @rem Try this path
+ CALL :TryToUseVisualStudio "%TESTED_VS_PATH%"
+GOTO :EOF
+
+@rem Test Visual Studio and set '%MSVC_HOME%' on success
+@rem %1 = tested path
+:TryToUseVisualStudio
+ SET "TESTED_VS_PATH=%~1"
+ IF NOT EXIST "%TESTED_VS_PATH%\VC\Auxiliary\Build\vcvarsall.bat" (
+ CALL :ECHO "-- VisualStudio '%TESTED_VS_PATH%' is bad: 'vcvarsall.bat' not found"
GOTO :EOF
)
- ECHO -- JDK '%%~I' looks good, selecting it
- SET SWT_JAVA_HOME=%%~I
-)
+ CALL :ECHO "-- VisualStudio '%TESTED_VS_PATH%' looks good, selecting it"
+ SET "MSVC_HOME=%TESTED_VS_PATH%"
+GOTO :EOF
+
+:TryToUseJdk
+ SET "TESTED_JDK_PATH_MASK=%~1"
+ @rem Loop over all directories matching mask.
+ @rem Note that directories are iterated in alphabetical order and *last* hit will
+ @rem be selected in hopes to select the highest available JDK version.
+ FOR /D %%I IN ("%TESTED_JDK_PATH_MASK%") DO (
+ IF NOT EXIST "%%~I" (
+ CALL :ECHO "-- JDK '%%~I' doesn't exist on disk"
+ GOTO :EOF
+ )
+ IF NOT EXIST "%%~I\include\jni.h" (
+ CALL :ECHO "-- JDK '%%~I' is bad: no jni.h"
+ GOTO :EOF
+ )
+ CALL :ECHO "-- JDK '%%~I' looks good, selecting it"
+ SET "SWT_JAVA_HOME=%%~I"
+ )
+GOTO :EOF
+
+@rem Regular ECHO has trouble with special characters such as ().
+@rem At the same time, if its argument is quoted, the quotes are printed literally.
+@rem The workaround is to escape all special characters with ^
+:ECHO
+SET "ECHO_STRING=%~1"
+SET "ECHO_STRING=%ECHO_STRING:<=^<%"
+SET "ECHO_STRING=%ECHO_STRING:>=^>%"
+SET "ECHO_STRING=%ECHO_STRING:(=^(%"
+SET "ECHO_STRING=%ECHO_STRING:)=^)%"
+ECHO %ECHO_STRING%
GOTO :EOF
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/make_win32.mak b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/make_win32.mak
index 7e9cf972e6..e70c3dd343 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/make_win32.mak
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/make_win32.mak
@@ -1,5 +1,5 @@
#*******************************************************************************
-# Copyright (c) 2000, 2018 IBM Corporation and others.
+# Copyright (c) 2000, 2022 IBM Corporation and others.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
index d4af8f36be..372eb78785 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2020 IBM Corporation and others.
+ * Copyright (c) 2000, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -2237,6 +2237,11 @@ public static final long SendMessage (long hWnd, int Msg, long wParam, TCHAR lPa
* expected to configure individual tweaks instead of calling this method.
* Please see <code>Display#setData()</code> and documentation for string keys
* used there.
+ * </p>
+ * <p>
+ * On GTK, behavior may be different as the boolean flag doesn't force dark
+ * theme instead it specify that dark theme is preferred.
+ * </p>
*
* @param isDarkTheme <code>true</code> for dark theme
*/
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
index 386a903097..b278236729 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2021 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2009, 2022 IBM Corporation and others. All rights reserved.
* The contents of this file are made available under the terms
* of the GNU Lesser General Public License (LGPL) Version 2.1 that
* accompanies this distribution (lgpl-v21.txt). The LGPL is also
@@ -84,33 +84,6 @@ fail:
}
#endif
-#ifndef NO_JSObjectMakeArray
-JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(JSObjectMakeArray)
- (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2, jlongArray arg3)
-{
- jlong *lparg2=NULL;
- jlong *lparg3=NULL;
- jlong rc = 0;
- WebKitGTK_NATIVE_ENTER(env, that, JSObjectMakeArray_FUNC);
- if (arg2) if ((lparg2 = (*env)->GetLongArrayElements(env, arg2, NULL)) == NULL) goto fail;
- if (arg3) if ((lparg3 = (*env)->GetLongArrayElements(env, arg3, NULL)) == NULL) goto fail;
-/*
- rc = (jlong)JSObjectMakeArray(arg0, arg1, lparg2, lparg3);
-*/
- {
- WebKitGTK_LOAD_FUNCTION(fp, JSObjectMakeArray)
- if (fp) {
- rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong, jlong, jlong *, jlong *))fp)(arg0, arg1, lparg2, lparg3);
- }
- }
-fail:
- if (arg3 && lparg3) (*env)->ReleaseLongArrayElements(env, arg3, lparg3, 0);
- if (arg2 && lparg2) (*env)->ReleaseLongArrayElements(env, arg2, lparg2, 0);
- WebKitGTK_NATIVE_EXIT(env, that, JSObjectMakeArray_FUNC);
- return rc;
-}
-#endif
-
#ifndef NO_JSStringCreateWithUTF8CString
JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(JSStringCreateWithUTF8CString)
(JNIEnv *env, jclass that, jbyteArray arg0)
@@ -217,86 +190,6 @@ JNIEXPORT jint JNICALL WebKitGTK_NATIVE(JSValueGetType)
}
#endif
-#ifndef NO_JSValueMakeBoolean
-JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(JSValueMakeBoolean)
- (JNIEnv *env, jclass that, jlong arg0, jint arg1)
-{
- jlong rc = 0;
- WebKitGTK_NATIVE_ENTER(env, that, JSValueMakeBoolean_FUNC);
-/*
- rc = (jlong)JSValueMakeBoolean(arg0, arg1);
-*/
- {
- WebKitGTK_LOAD_FUNCTION(fp, JSValueMakeBoolean)
- if (fp) {
- rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong, jint))fp)(arg0, arg1);
- }
- }
- WebKitGTK_NATIVE_EXIT(env, that, JSValueMakeBoolean_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_JSValueMakeNumber
-JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(JSValueMakeNumber)
- (JNIEnv *env, jclass that, jlong arg0, jdouble arg1)
-{
- jlong rc = 0;
- WebKitGTK_NATIVE_ENTER(env, that, JSValueMakeNumber_FUNC);
-/*
- rc = (jlong)JSValueMakeNumber(arg0, arg1);
-*/
- {
- WebKitGTK_LOAD_FUNCTION(fp, JSValueMakeNumber)
- if (fp) {
- rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong, jdouble))fp)(arg0, arg1);
- }
- }
- WebKitGTK_NATIVE_EXIT(env, that, JSValueMakeNumber_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_JSValueMakeString
-JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(JSValueMakeString)
- (JNIEnv *env, jclass that, jlong arg0, jlong arg1)
-{
- jlong rc = 0;
- WebKitGTK_NATIVE_ENTER(env, that, JSValueMakeString_FUNC);
-/*
- rc = (jlong)JSValueMakeString(arg0, arg1);
-*/
- {
- WebKitGTK_LOAD_FUNCTION(fp, JSValueMakeString)
- if (fp) {
- rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong, jlong))fp)(arg0, arg1);
- }
- }
- WebKitGTK_NATIVE_EXIT(env, that, JSValueMakeString_FUNC);
- return rc;
-}
-#endif
-
-#ifndef NO_JSValueMakeUndefined
-JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(JSValueMakeUndefined)
- (JNIEnv *env, jclass that, jlong arg0)
-{
- jlong rc = 0;
- WebKitGTK_NATIVE_ENTER(env, that, JSValueMakeUndefined_FUNC);
-/*
- rc = (jlong)JSValueMakeUndefined(arg0);
-*/
- {
- WebKitGTK_LOAD_FUNCTION(fp, JSValueMakeUndefined)
- if (fp) {
- rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong))fp)(arg0);
- }
- }
- WebKitGTK_NATIVE_EXIT(env, that, JSValueMakeUndefined_FUNC);
- return rc;
-}
-#endif
-
#ifndef NO_JSValueToNumber
JNIEXPORT jdouble JNICALL WebKitGTK_NATIVE(JSValueToNumber)
(JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlongArray arg2)
@@ -1321,6 +1214,28 @@ JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1response_1policy_1decision_1get
}
#endif
+#ifndef NO_webkit_1security_1manager_1register_1uri_1scheme_1as_1secure
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(webkit_1security_1manager_1register_1uri_1scheme_1as_1secure)
+ (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1)
+{
+ jbyte *lparg1=NULL;
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1security_1manager_1register_1uri_1scheme_1as_1secure_FUNC);
+ if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
+/*
+ webkit_security_manager_register_uri_scheme_as_secure(arg0, lparg1);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_security_manager_register_uri_scheme_as_secure)
+ if (fp) {
+ ((void (CALLING_CONVENTION*)(jlong, jbyte *))fp)(arg0, lparg1);
+ }
+ }
+fail:
+ if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1security_1manager_1register_1uri_1scheme_1as_1secure_FUNC);
+}
+#endif
+
#ifndef NO_webkit_1uri_1request_1get_1http_1headers
JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1uri_1request_1get_1http_1headers)
(JNIEnv *env, jclass that, jlong arg0)
@@ -1425,6 +1340,148 @@ JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1uri_1response_1get_1mime_1type)
}
#endif
+#ifndef NO_webkit_1uri_1scheme_1request_1finish
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(webkit_1uri_1scheme_1request_1finish)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1, jlong arg2, jbyteArray arg3)
+{
+ jbyte *lparg3=NULL;
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1uri_1scheme_1request_1finish_FUNC);
+ if (arg3) if ((lparg3 = (*env)->GetByteArrayElements(env, arg3, NULL)) == NULL) goto fail;
+/*
+ webkit_uri_scheme_request_finish(arg0, arg1, arg2, lparg3);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_uri_scheme_request_finish)
+ if (fp) {
+ ((void (CALLING_CONVENTION*)(jlong, jlong, jlong, jbyte *))fp)(arg0, arg1, arg2, lparg3);
+ }
+ }
+fail:
+ if (arg3 && lparg3) (*env)->ReleaseByteArrayElements(env, arg3, lparg3, JNI_ABORT);
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1uri_1scheme_1request_1finish_FUNC);
+}
+#endif
+
+#ifndef NO_webkit_1uri_1scheme_1request_1get_1uri
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1uri_1scheme_1request_1get_1uri)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1uri_1scheme_1request_1get_1uri_FUNC);
+/*
+ rc = (jlong)webkit_uri_scheme_request_get_uri(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_uri_scheme_request_get_uri)
+ if (fp) {
+ rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1uri_1scheme_1request_1get_1uri_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_webkit_1uri_1scheme_1request_1get_1web_1view
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1uri_1scheme_1request_1get_1web_1view)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1uri_1scheme_1request_1get_1web_1view_FUNC);
+/*
+ rc = (jlong)webkit_uri_scheme_request_get_web_view(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_uri_scheme_request_get_web_view)
+ if (fp) {
+ rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1uri_1scheme_1request_1get_1web_1view_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_webkit_1user_1content_1manager_1add_1script
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1user_1content_1manager_1add_1script)
+ (JNIEnv *env, jclass that, jlong arg0, jlong arg1)
+{
+ jlong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1user_1content_1manager_1add_1script_FUNC);
+/*
+ rc = (jlong)webkit_user_content_manager_add_script(arg0, arg1);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_user_content_manager_add_script)
+ if (fp) {
+ rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong, jlong))fp)(arg0, arg1);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1user_1content_1manager_1add_1script_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_webkit_1user_1content_1manager_1remove_1all_1scripts
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(webkit_1user_1content_1manager_1remove_1all_1scripts)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1user_1content_1manager_1remove_1all_1scripts_FUNC);
+/*
+ webkit_user_content_manager_remove_all_scripts(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_user_content_manager_remove_all_scripts)
+ if (fp) {
+ ((void (CALLING_CONVENTION*)(jlong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1user_1content_1manager_1remove_1all_1scripts_FUNC);
+}
+#endif
+
+#ifndef NO_webkit_1user_1script_1new
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1user_1script_1new)
+ (JNIEnv *env, jclass that, jbyteArray arg0, jint arg1, jint arg2, jlong arg3, jlong arg4)
+{
+ jbyte *lparg0=NULL;
+ jlong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1user_1script_1new_FUNC);
+ if (arg0) if ((lparg0 = (*env)->GetByteArrayElements(env, arg0, NULL)) == NULL) goto fail;
+/*
+ rc = (jlong)webkit_user_script_new(lparg0, arg1, arg2, arg3, arg4);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_user_script_new)
+ if (fp) {
+ rc = (jlong)((jlong (CALLING_CONVENTION*)(jbyte *, jint, jint, jlong, jlong))fp)(lparg0, arg1, arg2, arg3, arg4);
+ }
+ }
+fail:
+ if (arg0 && lparg0) (*env)->ReleaseByteArrayElements(env, arg0, lparg0, JNI_ABORT);
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1user_1script_1new_FUNC);
+ return rc;
+}
+#endif
+
+#ifndef NO_webkit_1user_1script_1unref
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(webkit_1user_1script_1unref)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1user_1script_1unref_FUNC);
+/*
+ webkit_user_script_unref(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_user_script_unref)
+ if (fp) {
+ ((void (CALLING_CONVENTION*)(jlong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1user_1script_1unref_FUNC);
+}
+#endif
+
#ifndef NO_webkit_1web_1context_1allow_1tls_1certificate_1for_1host
JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1web_1context_1allow_1tls_1certificate_1for_1host)
(JNIEnv *env, jclass that, jlong arg0, jlong arg1, jbyteArray arg2)
@@ -1489,6 +1546,26 @@ JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1web_1context_1get_1default)
}
#endif
+#ifndef NO_webkit_1web_1context_1get_1security_1manager
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1web_1context_1get_1security_1manager)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1web_1context_1get_1security_1manager_FUNC);
+/*
+ rc = (jlong)webkit_web_context_get_security_manager(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_web_context_get_security_manager)
+ if (fp) {
+ rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1web_1context_1get_1security_1manager_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_webkit_1web_1context_1get_1type
JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1web_1context_1get_1type)
(JNIEnv *env, jclass that)
@@ -1529,61 +1606,43 @@ JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1web_1context_1get_1website_1dat
}
#endif
-#ifndef NO_webkit_1web_1context_1set_1tls_1errors_1policy
-JNIEXPORT void JNICALL WebKitGTK_NATIVE(webkit_1web_1context_1set_1tls_1errors_1policy)
- (JNIEnv *env, jclass that, jlong arg0, jint arg1)
-{
- WebKitGTK_NATIVE_ENTER(env, that, webkit_1web_1context_1set_1tls_1errors_1policy_FUNC);
-/*
- webkit_web_context_set_tls_errors_policy(arg0, arg1);
-*/
- {
- WebKitGTK_LOAD_FUNCTION(fp, webkit_web_context_set_tls_errors_policy)
- if (fp) {
- ((void (CALLING_CONVENTION*)(jlong, jint))fp)(arg0, arg1);
- }
- }
- WebKitGTK_NATIVE_EXIT(env, that, webkit_1web_1context_1set_1tls_1errors_1policy_FUNC);
-}
-#endif
-
-#ifndef NO_webkit_1web_1context_1set_1web_1extensions_1directory
-JNIEXPORT void JNICALL WebKitGTK_NATIVE(webkit_1web_1context_1set_1web_1extensions_1directory)
- (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1)
+#ifndef NO_webkit_1web_1context_1register_1uri_1scheme
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(webkit_1web_1context_1register_1uri_1scheme)
+ (JNIEnv *env, jclass that, jlong arg0, jbyteArray arg1, jlong arg2, jlong arg3, jlong arg4)
{
jbyte *lparg1=NULL;
- WebKitGTK_NATIVE_ENTER(env, that, webkit_1web_1context_1set_1web_1extensions_1directory_FUNC);
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1web_1context_1register_1uri_1scheme_FUNC);
if (arg1) if ((lparg1 = (*env)->GetByteArrayElements(env, arg1, NULL)) == NULL) goto fail;
/*
- webkit_web_context_set_web_extensions_directory(arg0, lparg1);
+ webkit_web_context_register_uri_scheme(arg0, lparg1, arg2, arg3, arg4);
*/
{
- WebKitGTK_LOAD_FUNCTION(fp, webkit_web_context_set_web_extensions_directory)
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_web_context_register_uri_scheme)
if (fp) {
- ((void (CALLING_CONVENTION*)(jlong, jbyte *))fp)(arg0, lparg1);
+ ((void (CALLING_CONVENTION*)(jlong, jbyte *, jlong, jlong, jlong))fp)(arg0, lparg1, arg2, arg3, arg4);
}
}
fail:
if (arg1 && lparg1) (*env)->ReleaseByteArrayElements(env, arg1, lparg1, 0);
- WebKitGTK_NATIVE_EXIT(env, that, webkit_1web_1context_1set_1web_1extensions_1directory_FUNC);
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1web_1context_1register_1uri_1scheme_FUNC);
}
#endif
-#ifndef NO_webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data
-JNIEXPORT void JNICALL WebKitGTK_NATIVE(webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data)
- (JNIEnv *env, jclass that, jlong arg0, jlong arg1)
+#ifndef NO_webkit_1web_1context_1set_1tls_1errors_1policy
+JNIEXPORT void JNICALL WebKitGTK_NATIVE(webkit_1web_1context_1set_1tls_1errors_1policy)
+ (JNIEnv *env, jclass that, jlong arg0, jint arg1)
{
- WebKitGTK_NATIVE_ENTER(env, that, webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data_FUNC);
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1web_1context_1set_1tls_1errors_1policy_FUNC);
/*
- webkit_web_context_set_web_extensions_initialization_user_data(arg0, arg1);
+ webkit_web_context_set_tls_errors_policy(arg0, arg1);
*/
{
- WebKitGTK_LOAD_FUNCTION(fp, webkit_web_context_set_web_extensions_initialization_user_data)
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_web_context_set_tls_errors_policy)
if (fp) {
- ((void (CALLING_CONVENTION*)(jlong, jlong))fp)(arg0, arg1);
+ ((void (CALLING_CONVENTION*)(jlong, jint))fp)(arg0, arg1);
}
}
- WebKitGTK_NATIVE_EXIT(env, that, webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data_FUNC);
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1web_1context_1set_1tls_1errors_1policy_FUNC);
}
#endif
@@ -1832,6 +1891,26 @@ JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1web_1view_1get_1uri)
}
#endif
+#ifndef NO_webkit_1web_1view_1get_1user_1content_1manager
+JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1web_1view_1get_1user_1content_1manager)
+ (JNIEnv *env, jclass that, jlong arg0)
+{
+ jlong rc = 0;
+ WebKitGTK_NATIVE_ENTER(env, that, webkit_1web_1view_1get_1user_1content_1manager_FUNC);
+/*
+ rc = (jlong)webkit_web_view_get_user_content_manager(arg0);
+*/
+ {
+ WebKitGTK_LOAD_FUNCTION(fp, webkit_web_view_get_user_content_manager)
+ if (fp) {
+ rc = (jlong)((jlong (CALLING_CONVENTION*)(jlong))fp)(arg0);
+ }
+ }
+ WebKitGTK_NATIVE_EXIT(env, that, webkit_1web_1view_1get_1user_1content_1manager_FUNC);
+ return rc;
+}
+#endif
+
#ifndef NO_webkit_1web_1view_1get_1window_1properties
JNIEXPORT jlong JNICALL WebKitGTK_NATIVE(webkit_1web_1view_1get_1window_1properties)
(JNIEnv *env, jclass that, jlong arg0)
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.c
deleted file mode 100644
index cd9a5e15fd..0000000000
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.c
+++ /dev/null
@@ -1,616 +0,0 @@
-#include "webkitgtk_extension.h"
-
-/*
- * To debug this extension:
- * -ensure this is built with debug flags (look for '-g*' in make_linux, or 'SWT_LIB_DEBUG' macro)
- * -connect to the WebKitWebProcess with the PID of this extension. It can be found as follows:
- g_print("Extension PID: %d\n", getpid());
- */
-
-// Client address of the main process GDBusServer -- the extension connects to this
-const gchar *swt_main_proc_client_address = NULL;
-
-// Client address of the extension's GDBusServer -- SWT main process connects to this
-const gchar *extension_server_address = NULL;
-
-// See: WebKitGTK.java's 'TYPE NOTES'
-guchar SWT_DBUS_MAGIC_NUMBER_EMPTY_ARRAY = 101;
-guchar SWT_DBUS_MAGIC_NUMBER_NULL = 48;
-
-// This struct represents a BrowserFunction
-typedef struct {
- guint64 page_id; // page ID
- gchar *function; // JS function
- gchar *url; // URL the function belongs to
-} BrowserFunction;
-
-// The list of BrowserFunctions registered to this extension
-GSList *function_list = NULL;
-
-// GDBusConnection to the SWT main process
-GDBusConnection *connection_to_main_proc = NULL;
-
-// This extension's GDBusServer and related resources
-GDBusServer *server = NULL;
-GDBusAuthObserver *auth_observer = NULL;
-gchar *guid = NULL;
-
-// GDBusConnection from SWT main process
-GDBusConnection *connection_from_main_proc = NULL;
-
-/**
- * Caller should free the returned GVariant
- */
-GVariant *call_main_proc_sync(char * method_name, GVariant *parameters) {
- GError *error = NULL; // Some functions return errors through params
- GVariant *result; // The value result from a call
-
- // Send a message
- result = g_dbus_connection_call_sync(connection_to_main_proc, WEBKIT_MAIN_PROCESS_DBUS_NAME,
- WEBKIT_MAIN_PROCESS_OBJECT_PATH, WEBKIT_MAIN_PROCESS_INTERFACE_NAME, method_name, parameters,
- NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
- // Error checking.
- if (result == NULL) {
- if (error != NULL) {
- g_error("call_main_proc_sync failed because '%s.'\n", error->message);
- } else {
- g_error("call_main_proc_sync failed for an unknown reason.\n");
- }
- return NULL;
- }
-
- return result;
-}
-
-// +--------------------------------------------------+
-// | JavaScriptCore to/from conversion GVariant logic |
-// +--------------------------------------------------+
-
-/** Return true if the given JSValueRef is one we can push over gdbus. False otherwise.
- * We support basic types, nulls and arrays of basic types.*/
-gboolean is_js_valid(JSContextRef context, JSValueRef value) {
- JSType type = JSValueGetType(context, value);
- if (type == kJSTypeBoolean
- || type == kJSTypeNumber
- || type == kJSTypeString
- || type == kJSTypeNull
- || type == kJSTypeUndefined) {
- return true;
- }
- if (type == kJSTypeObject && JSValueIsArray(context, value)) {
- JSStringRef propertyName = JSStringCreateWithUTF8CString("length");
- JSObjectRef object = JSValueToObject(context, value, NULL);
- JSValueRef valuePtr = JSObjectGetProperty(context, object, propertyName, NULL);
- JSStringRelease(propertyName);
- int length = (int) JSValueToNumber(context, valuePtr, NULL);
- int i;
- for (i = 0; i < length; i++) {
- const JSValueRef child = JSObjectGetPropertyAtIndex(context, object, i, NULL);
- if (!is_js_valid(context, child)) {
- return false;
- }
- }
- return true;
- }
- return false;
-}
-
-/*
- * Developer note:
- * JavaScriptCore defines a "Number" to be a double in general. It doesn't seem to be using "Int".
- */
-static GVariant * convert_js_to_gvariant (JSContextRef context, JSValueRef value){
- g_assert(context != NULL);
- g_assert(value != NULL);
- JSType type = JSValueGetType(context, value);
-
- if (type == kJSTypeBoolean) {
- gboolean result = JSValueToNumber(context, value, NULL) != 0;
- return g_variant_new_boolean(result);
- }
-
- if (type == kJSTypeNumber) {
- double result = JSValueToNumber(context, value, NULL);
- return g_variant_new_double(result);
- }
-
- if (type == kJSTypeString) {
- JSStringRef stringRef = JSValueToStringCopy(context, value, NULL);
- size_t length = JSStringGetMaximumUTF8CStringSize(stringRef);
- char* string = (char*) malloc(length);
- JSStringGetUTF8CString(stringRef, string, length);
- GVariant *variant = g_variant_new_string(string);
- free(string);
- return variant;
- }
-
- if (type == kJSTypeNull || type == kJSTypeUndefined) {
- return g_variant_new_byte(SWT_DBUS_MAGIC_NUMBER_NULL);
- }
-
- if (type == kJSTypeObject) {
- JSStringRef propertyName = JSStringCreateWithUTF8CString("length");
- JSObjectRef object = JSValueToObject(context, value, NULL);
- JSValueRef valuePtr = JSObjectGetProperty(context, object, propertyName, NULL);
- JSStringRelease(propertyName);
-
- if (JSValueGetType(context, valuePtr) == kJSTypeNumber) {
- int length = (int) JSValueToNumber(context, valuePtr, NULL);
-
- if (length == 0) {
- return g_variant_new_byte(SWT_DBUS_MAGIC_NUMBER_EMPTY_ARRAY);
- }
- GVariant **children = g_new(GVariant *, length);
- int i = 0;
- for (i = 0; i < length; i++) {
- const JSValueRef child = JSObjectGetPropertyAtIndex(context, object, i, NULL);
- children[i] = convert_js_to_gvariant(context, child);
- }
- GVariant* variant = g_variant_new_tuple(children, length);
- g_free(children);
- return variant;
- }
- }
-
- // Get type value string
- JSStringRef valueIString = JSValueToStringCopy(context, value, NULL);
- size_t valueUTF8Size = JSStringGetMaximumUTF8CStringSize(valueIString);
- char* valueUTF8 = (char*) malloc(valueUTF8Size);
- JSStringGetUTF8CString(valueIString, valueUTF8, valueUTF8Size);
-
- g_warning("Unhandled type %d value: %s \n", type, valueUTF8);
- free(valueUTF8);
- JSStringRelease(valueIString);
-
- return NULL;
-}
-
-
-static JSValueRef convert_gvariant_to_js (JSContextRef context, GVariant * value){
- g_assert(context != NULL);
- g_assert(value != NULL);
-
- if (g_variant_is_of_type(value, G_VARIANT_TYPE_BYTE)) { // see: WebKitGTK.java 'TYPE NOTES'
- guchar magic_number = g_variant_get_byte(value);
- if (magic_number == SWT_DBUS_MAGIC_NUMBER_NULL) {
- // 'JSValueMakeUndefined' is used as oppose to 'JSValueMakeNull' (from what I gather) for legacy reasons.
- // I.e webkit1 used it, so we shall use it in webkit2 also.
- return JSValueMakeUndefined(context);
- } else if (magic_number == SWT_DBUS_MAGIC_NUMBER_EMPTY_ARRAY) {
- return JSObjectMakeArray(context, 0, NULL, NULL); // The empty array with no children.
- } else {
- g_error("Java sent an unknown magic number: '%d' , this should never happen. \n", magic_number);
- }
- }
-
- if (g_variant_is_of_type(value, G_VARIANT_TYPE_BOOLEAN)) {
- return JSValueMakeBoolean(context, g_variant_get_boolean(value));
- }
-
- if (g_variant_is_of_type(value, G_VARIANT_TYPE_DOUBLE)) {
- return JSValueMakeNumber(context, g_variant_get_double(value));
- }
-
- if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
- JSStringRef stringRef = JSStringCreateWithUTF8CString(g_variant_get_string(value, NULL));
- JSValueRef result = JSValueMakeString(context, stringRef);
- JSStringRelease(stringRef);
- return result;
- }
-
- if (g_variant_is_of_type(value, G_VARIANT_TYPE_TUPLE)) {
- gsize length = g_variant_n_children(value);
- JSValueRef *children = g_new(JSValueRef, length);
-
- gsize i = 0;
- for (i = 0; i < length; i++) {
- children[i] = convert_gvariant_to_js(context, g_variant_get_child_value(value, i));
- }
- JSValueRef result = JSObjectMakeArray(context, length, children, NULL);
- g_free(children);
- return result;
- }
- g_error("Unhandled type %s \n", g_variant_get_type_string(value));
- return NULL;
-}
-
-// +--------------------+---------------------------------------------------------
-// | WebExtension Logic |
-// +--------------------+
-
-// Reached by calling "webkit2callJava();" in javascript console.
-// Some basic c function to be exposed to the javascript environment
-static JSValueRef webkit2callJava (JSContextRef context,
- JSObjectRef function,
- JSObjectRef thisObject,
- size_t argumentCount,
- const JSValueRef arguments[], // [String webview, double index, String Token, Object[] args]
- JSValueRef *exception) {
- g_assert (argumentCount == 4);
- GVariant *g_var_params; // The parameters to a function call
-
- // Need to ensure user arguments won't break gdbus.
- if (!is_js_valid(context, arguments[3])) {
- g_warning("Arguments contain an invalid type (object). Only Number,Boolean,null,String and (mixed) arrays of basic types are supported");
- return 0;
- }
-
- g_var_params = g_variant_new ("(@s@d@s@*)", // pointer to String, pointer to double, pointer to string, pointer to any type.
- convert_js_to_gvariant(context, arguments[0]), // String webView
- convert_js_to_gvariant(context, arguments[1]), // int index
- convert_js_to_gvariant(context, arguments[2]), // String Token
- convert_js_to_gvariant(context, arguments[3]) // js args
- );
-
- GVariant *g_var_result = call_main_proc_sync("webkit2callJava", g_var_params);
- if (g_var_result == NULL) {
- g_error("Java call returned NULL. This should never happpen\n");
- return 0;
- }
-
- // gdbus dynamic call always returns an array(tuple) with return types.
- // In our case, we return a single type or an array.
- // E.g java:int -> gdbus:(i) (array containing one int)
- // E.g java [int,str] -> gdbus:((is)) (array with array of (int+str).
- // So we always extract the first child, convert and pass to js.
- JSValueRef retVal = 0;
- if (g_variant_is_of_type(g_var_result, G_VARIANT_TYPE_TUPLE)) {
- if (g_variant_n_children(g_var_result) != 1) {
- g_error("Should only receive a single item in the tuple, but length is: %ud\n", (unsigned int) g_variant_n_children(g_var_result));
- }
- retVal = convert_gvariant_to_js(context, g_variant_get_child_value(g_var_result, 0));
- } else {
- g_error("Unsupported return type. Should be an array, but received a single type.\n");
- }
-
- g_variant_unref(g_var_result);
- return retVal;
-}
-
-static void web_page_created_callback(WebKitWebExtension *extension, WebKitWebPage *web_page, gpointer user_data) {
- // Observation. This seems to be called only once.
-}
-
-/**
- * Returns the main frame of the WebPage with the given ID
- */
-static WebKitFrame *webkitgtk_extension_get_main_frame (const guint64 id) {
- WebKitWebPage *web_page = webkit_web_extension_get_page (this_extension, id);
- return webkit_web_page_get_main_frame (web_page);
-}
-
-/*
- * Execute the Javascript for the given page and URL.
- */
-static gboolean webkitgtk_extension_execute_script (const guint64 page_id, gchar* script, gchar* url) {
- WebKitFrame *main_frame = webkitgtk_extension_get_main_frame (page_id);
-
- JSStringRef url_string = JSStringCreateWithUTF8CString (url);
- JSStringRef script_string = JSStringCreateWithUTF8CString (script);
-
- /*
- * TODO Bug 570285: Replace with webkit_frame_get_js_context()
- * when minimal WebKitGTK version is 2.22+
- */
- G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- JSGlobalContextRef context = webkit_frame_get_javascript_global_context (main_frame);
- G_GNUC_END_IGNORE_DEPRECATIONS
-
- JSValueRef exception;
- JSValueRef result = JSEvaluateScript(context, script_string, NULL, url_string, 0, &exception);
- if (!result) {
- JSStringRef exceptionIString = JSValueToStringCopy(context, exception, NULL);
- size_t exceptionUTF8Size = JSStringGetMaximumUTF8CStringSize(exceptionIString);
- char* exceptionUTF8 = (char*)malloc(exceptionUTF8Size);
- JSStringGetUTF8CString(exceptionIString, exceptionUTF8, exceptionUTF8Size);
- g_error("Failed to execute script exception: %s\n", exceptionUTF8);
- free(exceptionUTF8);
- JSStringRelease(exceptionIString);
- }
-
- JSStringRelease (url_string);
- JSStringRelease (script_string);
-
- return result != NULL;
-}
-
-void execute_browser_functions(gconstpointer item, gpointer page) {
- BrowserFunction *function = (BrowserFunction *) item;
- if (function != NULL && function->page_id == GPOINTER_TO_UINT(page)) {
- webkitgtk_extension_execute_script(function->page_id, function->function, function->url);
- }
- return;
-}
-
-gint find_browser_function (gconstpointer item, gconstpointer target) {
- BrowserFunction *element = (BrowserFunction *) item;
- BrowserFunction *remove = (BrowserFunction *) target;
- if (element->page_id == remove->page_id && g_strcmp0(element->function, remove->function) == 0 &&
- g_strcmp0(element->url, remove->url) == 0) {
- return 0;
- }
- return 1;
-}
-
-void add_browser_function(guint64 page_id, const gchar *function, const gchar *url) {
- BrowserFunction *func = g_slice_new0(BrowserFunction);
- func->page_id = page_id;
- func->function = g_strdup(function);
- func->url = g_strdup(url);
- function_list = g_slist_append(function_list, func);
-}
-
-void remove_browser_function(guint64 page_id, const gchar *function, const gchar *url) {
- BrowserFunction *func = g_slice_new0(BrowserFunction);
- func->page_id = page_id;
- func->function = g_strdup(function);
- func->url = g_strdup(url);
- GSList *to_remove = g_slist_find_custom(function_list, func, find_browser_function);
- if (to_remove != NULL) {
- BrowserFunction *delete_func = to_remove->data;
- g_free(delete_func->function);
- g_free(delete_func->url);
- function_list = g_slist_delete_link(function_list, to_remove);
- }
- g_free(func->function);
- g_free(func->url);
- g_slice_free(BrowserFunction, func);
-}
-
-void unpack_browser_function_array(GVariant *array) {
- GVariantIter iter;
- GVariant *child;
-
- g_variant_iter_init (&iter, array);
- while ((child = g_variant_iter_next_value (&iter))) {
- gsize length = (int)g_variant_n_children (child);
- if (length > 3) {
- // If the length is longer than three, something went wrong and this tuple should be skipped
- g_warning("There was an error unpacking the GVariant tuple for a BrowserFunction in the web extension.\n");
- continue;
- }
- guint64 page = g_variant_get_uint64(g_variant_get_child_value(child, 0));
- if (page == -1UL) {
- // Empty or malformed BrowserFunction, skip this one
- continue;
- } else {
- const gchar *function = g_variant_get_string(g_variant_get_child_value(child, 1), NULL);
- const gchar *url = g_variant_get_string(g_variant_get_child_value(child, 2), NULL);
- if (function != NULL && url != NULL) {
- add_browser_function(page, function, url);
- } else {
- g_warning("There was an error unpacking the function string or URL.\n");
- }
- }
- g_variant_unref (child);
- }
-}
-
-/*
- * Every time a webpage is loaded, we should re-register the 'webkit2callJava' function.
- * Additionally, we re-register all BrowserFunctions that are stored in the function_list
- * GSList.
- */
-static void window_object_cleared_callback (WebKitScriptWorld *world, WebKitWebPage *web_page,
- WebKitFrame *frame,
- gpointer user_data) {
- // Observation: This is called every time a webpage is loaded.
- JSGlobalContextRef jsContext;
- JSObjectRef globalObject;
- JSValueRef exception = 0;
-
- /*
- * TODO Bug 570285: Replace with webkit_frame_get_js_context_for_script_world()
- * when minimal WebKitGTK version is 2.22+
- */
- G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- jsContext = webkit_frame_get_javascript_context_for_script_world (frame, world);
- G_GNUC_END_IGNORE_DEPRECATIONS
- globalObject = JSContextGetGlobalObject (jsContext);
-
- JSStringRef function_name = JSStringCreateWithUTF8CString("webkit2callJava"); // Func reference by javascript
- JSObjectRef jsFunction = JSObjectMakeFunctionWithCallback(jsContext, function_name, webkit2callJava); // C reference to func
- JSObjectSetProperty(jsContext, globalObject, function_name, jsFunction,
- kJSPropertyAttributeDontDelete | kJSPropertyAttributeReadOnly, &exception);
-
- if (exception) {
- g_print("OJSObjectSetProperty exception occurred");
- }
-
- /*
- * Iterate over the list of BrowserFunctions and execute each one of them for the current page.
- * This ensures that BrowserFunctions are not lost on page reloads. See bug 536141.
- */
- if (function_list != NULL) {
- guint64 page_id = webkit_web_page_get_id (web_page);
- if (page_id != -1UL) {
- g_slist_foreach(function_list, (GFunc)execute_browser_functions, GUINT_TO_POINTER(page_id));
- } else {
- g_warning("There was an error fetching the page ID in the object_cleared callback.\n");
- }
- }
-}
-
-static void
-webkitgtk_extension_handle_method_call (GDBusConnection *connection, const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation,
- gpointer user_data) {
- gboolean result = FALSE;
- const gchar *script;
- const gchar *url;
- guint64 page_id;
- // Check method names
- if (g_strcmp0(method_name, "webkitgtk_extension_register_function") == 0) {
- g_variant_get(parameters, "(t&s&s)", &page_id, &script, &url);
- if (page_id != -1UL) {
- result = TRUE;
- // Return before processing the linked list, to prevent DBus from hanging
- g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", result));
- add_browser_function(page_id, script, url);
- return;
- }
- g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", result));
- return;
- }
- if (g_strcmp0(method_name, "webkitgtk_extension_deregister_function") == 0) {
- g_variant_get(parameters, "(t&s&s)", &page_id, &script, &url);
- if (page_id != -1UL) {
- result = TRUE;
- // Return before processing the linked list, to prevent DBus from hanging
- g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", result));
- remove_browser_function(page_id, script, url);
- return;
- }
- g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", result));
- return;
- }
- g_error ("Unknown method %s\n", method_name);
-}
-
-static const GDBusInterfaceVTable interface_vtable = {.method_call = webkitgtk_extension_handle_method_call};
-
-static void connection_closed_cb (GDBusConnection *connection, gboolean remote_peer_vanished, GError *error,
- gpointer user_data) {
- /*
- * If this connection is closed we can shut the server down. NOTE: all connections are freed in the main
- * SWT process, including connections created here in this extension. This is done for the sake of
- * consistency to avoid double frees.
- */
- if (connection == connection_from_main_proc) {
- // Free server and its objects
- g_dbus_server_stop(server);
- g_object_unref(auth_observer);
- g_object_unref(server);
- g_free(guid);
- }
-}
-
-static gboolean new_connection_cb (GDBusServer *server, GDBusConnection *connection, gpointer user_data) {
- // Create introspection XML
- dbus_introspection_xml = g_new (gchar, strlen(dbus_introspection_xml_template) +
- strlen(WEBKITGTK_EXTENSION_INTERFACE_NAME) + 1);
- g_sprintf (dbus_introspection_xml, dbus_introspection_xml_template, WEBKITGTK_EXTENSION_INTERFACE_NAME);
-
- // Create DBus node
- dbus_node = g_dbus_node_info_new_for_xml (dbus_introspection_xml, NULL);
- g_assert (dbus_node != NULL);
-
- // Register node on the connection that was just created
- dbus_interface = g_dbus_node_info_lookup_interface(dbus_node, WEBKITGTK_EXTENSION_INTERFACE_NAME);
- guint registration_id = g_dbus_connection_register_object(connection, WEBKITGTK_EXTENSION_OBJECT_PATH,
- dbus_interface,
- &interface_vtable, NULL, /* user_data */
- NULL, /* user_data_free_func */
- NULL); /* GError** */
- g_assert(registration_id > 0);
-
- // This connection will be the one from the main SWT process
- connection_from_main_proc = g_object_ref(connection);
-
- // Listen to the "close" signal on this connection so we can free resources in the extension when
- // the time comes.
- g_signal_connect(connection_from_main_proc, "closed", G_CALLBACK (connection_closed_cb), NULL);
-
- return 1;
-}
-
-static gboolean extension_authorize_peer (GDBusAuthObserver *observer, GIOStream *stream, GCredentials *credentials,
- gpointer user_data) {
- g_autoptr (GError) error = NULL;
- gboolean authorized = FALSE;
- if (credentials != NULL) {
- GCredentials *own_credentials;
- own_credentials = g_credentials_new ();
- if (g_credentials_is_same_user (credentials, own_credentials, &error)) {
- authorized = TRUE;
- }
- g_object_unref (own_credentials);
- }
- if (error) {
- g_warning ("Error authenticating client connection: %s", error->message);
- }
- return authorized;
-}
-
-// Returns a valid GDBusServer address -- this will be the address used to connect to the extension's
-// GDBusServer. On Linux, the address required is used for as an abstract path. If abstract path is not supported
-// one must create & manage temporary directories. See Bug562443.
-gchar *construct_server_address () {
- gchar *tmp_address = g_strdup("unix:tmpdir=/tmp/SWT-WebExtensionGDBusServer");
-
- return tmp_address;
-}
-
-// Creates the GDBusServer for this web extension
-static void create_server () {
- g_autoptr (GError) error = NULL;
- extension_server_address = construct_server_address();
- auth_observer = g_dbus_auth_observer_new();
-
- guid = g_dbus_generate_guid();
- server = g_dbus_server_new_sync(extension_server_address, G_DBUS_SERVER_FLAGS_NONE, guid,
- auth_observer, NULL, &error);
-
- if (error) {
- g_error ("Failed to create server: %s", error->message);
- }
-
- if (server) {
- g_signal_connect(server, "new-connection", G_CALLBACK(new_connection_cb), NULL);
- g_dbus_server_start(server);
- g_signal_connect (auth_observer, "authorize-authenticated-peer", G_CALLBACK(extension_authorize_peer), NULL);
- }
-}
-
-// Identifies this web extension to the main SWT process by sending its
-// server address over DBus.
-static void identify_extension_to_main_proc () {
- const gchar *client_address_for_extension_server = g_dbus_server_get_client_address(server);
- GVariant *result = call_main_proc_sync("webkitWebExtensionIdentifier", g_variant_new ("(s)",
- client_address_for_extension_server));
-
- // Process and register any pending BrowserFunctions from the main SWT process
- if (g_variant_is_of_type(result, G_VARIANT_TYPE_TUPLE)) {
- unpack_browser_function_array(g_variant_get_child_value(result, 0));
- } else {
- g_warning("webkitWebExtensionIdentifier return value from SWT was an unexpected type""(not a tuple).\n");
- }
-}
-
-// Creates a GDBusConnection to the main SWT process
-static void connect_to_main_proc (GVariant *user_data) {
- swt_main_proc_client_address = g_variant_get_string(user_data, NULL);
-
- g_autoptr (GError) error = NULL;
- connection_to_main_proc = g_dbus_connection_new_for_address_sync (swt_main_proc_client_address,
- G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, NULL, NULL, &error);
-
- if (error) {
- g_error ("Failed to create connection: %s", error->message);
- }
-
- if (connection_to_main_proc && g_dbus_connection_is_closed(connection_to_main_proc)) {
- g_error ("Failed to created connection: connection is closed");
- }
-}
-
-G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data(WebKitWebExtension *extension, GVariant *user_data) {
- this_extension = extension;
-
- // Connect to the main SWT process
- connect_to_main_proc(user_data);
-
- // Create this extension's GDBusServer
- create_server();
-
- // Identify this extension's server address to the main process
- identify_extension_to_main_proc();
-
- // WebKit callbacks
- g_signal_connect(extension, "page-created", G_CALLBACK(web_page_created_callback), NULL);
- g_signal_connect (webkit_script_world_get_default (), "window-object-cleared", G_CALLBACK (window_object_cleared_callback), NULL);
-}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.h b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.h
deleted file mode 100644
index 3edca55451..0000000000
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_extension.h
+++ /dev/null
@@ -1,74 +0,0 @@
- /*******************************************************************************
- * Copyright (c) 2017 Red Hat and others. All rights reserved.
- * The contents of this file are made available under the terms
- * of the GNU Lesser General Public License (LGPL) Version 2.1 that
- * accompanies this distribution (lgpl-v21.txt). The LGPL is also
- * available at http://www.gnu.org/licenses/lgpl.html. If the version
- * of the LGPL at http://www.gnu.org is different to the version of
- * the LGPL accompanying this distribution and there is any conflict
- * between the two license versions, the terms of the LGPL accompanying
- * this distribution shall govern.
- *
- * Contributors:
- * Red Hat - initial API and implementation
- *******************************************************************************/
-#ifndef INC_webkit_extension_H
-#define INC_webkit_extension_H
-
-#include <string.h>
-
-#include <glib.h>
-#include <glib/gprintf.h>
-
-#include <gio/gio.h>
-#include <stdlib.h>
-
-#include <unistd.h>
-#include <stdio.h>
-
-// These 2 are only for getpid();
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <webkit2/webkit-web-extension.h>
-
-#include <JavaScriptCore/JavaScript.h>
-#include <JavaScriptCore/JSContextRef.h>
-#include <JavaScriptCore/JSObjectRef.h>
-#include <JavaScriptCore/JSStringRef.h>
-
-#define WEBKITGTK_EXTENSION_DBUS_NAME "org.eclipse.swt.webkitgtk_extension"
-#define WEBKITGTK_EXTENSION_OBJECT_PATH "/org/eclipse/swt/webkitgtk_extension/gdbus"
-#define WEBKITGTK_EXTENSION_INTERFACE_NAME "org.eclipse.swt.webkitgtk_extension.gdbusInterface"
-
-#define WEBKIT_MAIN_PROCESS_DBUS_NAME "org.eclipse.swt"
-#define WEBKIT_MAIN_PROCESS_OBJECT_PATH "/org/eclipse/swt/gdbus"
-#define WEBKIT_MAIN_PROCESS_INTERFACE_NAME "org.eclipse.swt.gdbusInterface"
-
-static WebKitWebExtension *this_extension;
-
-static GDBusNodeInfo *dbus_node;
-static GDBusInterfaceInfo *dbus_interface;
-static gchar* dbus_introspection_xml;
-static gchar* dbus_introspection_xml_template =
-"<node>"
- "<interface name='%s'>"
-
- "<method name='webkitgtk_extension_register_function'>"
- "<arg type='t' name='page_id' direction='in'/>"
- "<arg type='s' name='script' direction='in'/>"
- "<arg type='s' name='url' direction='in'/>"
- "<arg type='b' name='result' direction='out'/>"
- "</method>"
-
- "<method name='webkitgtk_extension_deregister_function'>"
- "<arg type='t' name='page_id' direction='in'/>"
- "<arg type='s' name='script' direction='in'/>"
- "<arg type='s' name='url' direction='in'/>"
- "<arg type='b' name='result' direction='out'/>"
- "</method>"
-
- "</interface>"
-"</node>";
-
-#endif /*INC_webkit_extension_H*/
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
index 9a18355034..cc0c92c301 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2021 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2009, 2022 IBM Corporation and others. All rights reserved.
* The contents of this file are made available under the terms
* of the GNU Lesser General Public License (LGPL) Version 2.1 that
* accompanies this distribution (lgpl-v21.txt). The LGPL is also
@@ -25,16 +25,11 @@ char * WebKitGTK_nativeFunctionNames[] = {
"GdkRectangle_1sizeof",
"JSObjectGetProperty",
"JSObjectGetPropertyAtIndex",
- "JSObjectMakeArray",
"JSStringCreateWithUTF8CString",
"JSStringGetMaximumUTF8CStringSize",
"JSStringGetUTF8CString",
"JSStringRelease",
"JSValueGetType",
- "JSValueMakeBoolean",
- "JSValueMakeNumber",
- "JSValueMakeString",
- "JSValueMakeUndefined",
"JSValueToNumber",
"JSValueToStringCopy",
"soup_1cookie_1get_1name",
@@ -85,19 +80,27 @@ char * WebKitGTK_nativeFunctionNames[] = {
"webkit_1policy_1decision_1ignore",
"webkit_1response_1policy_1decision_1get_1request",
"webkit_1response_1policy_1decision_1get_1response",
+ "webkit_1security_1manager_1register_1uri_1scheme_1as_1secure",
"webkit_1uri_1request_1get_1http_1headers",
"webkit_1uri_1request_1get_1uri",
"webkit_1uri_1request_1new",
"webkit_1uri_1response_1get_1content_1length",
"webkit_1uri_1response_1get_1mime_1type",
+ "webkit_1uri_1scheme_1request_1finish",
+ "webkit_1uri_1scheme_1request_1get_1uri",
+ "webkit_1uri_1scheme_1request_1get_1web_1view",
+ "webkit_1user_1content_1manager_1add_1script",
+ "webkit_1user_1content_1manager_1remove_1all_1scripts",
+ "webkit_1user_1script_1new",
+ "webkit_1user_1script_1unref",
"webkit_1web_1context_1allow_1tls_1certificate_1for_1host",
"webkit_1web_1context_1get_1cookie_1manager",
"webkit_1web_1context_1get_1default",
+ "webkit_1web_1context_1get_1security_1manager",
"webkit_1web_1context_1get_1type",
"webkit_1web_1context_1get_1website_1data_1manager",
+ "webkit_1web_1context_1register_1uri_1scheme",
"webkit_1web_1context_1set_1tls_1errors_1policy",
- "webkit_1web_1context_1set_1web_1extensions_1directory",
- "webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data",
"webkit_1web_1resource_1get_1data",
"webkit_1web_1resource_1get_1data_1finish",
"webkit_1web_1view_1can_1go_1back",
@@ -110,6 +113,7 @@ char * WebKitGTK_nativeFunctionNames[] = {
"webkit_1web_1view_1get_1settings",
"webkit_1web_1view_1get_1title",
"webkit_1web_1view_1get_1uri",
+ "webkit_1web_1view_1get_1user_1content_1manager",
"webkit_1web_1view_1get_1window_1properties",
"webkit_1web_1view_1go_1back",
"webkit_1web_1view_1go_1forward",
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
index a94d3e7565..c189b555b1 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2021 IBM Corporation and others. All rights reserved.
+ * Copyright (c) 2009, 2022 IBM Corporation and others. All rights reserved.
* The contents of this file are made available under the terms
* of the GNU Lesser General Public License (LGPL) Version 2.1 that
* accompanies this distribution (lgpl-v21.txt). The LGPL is also
@@ -35,16 +35,11 @@ typedef enum {
GdkRectangle_1sizeof_FUNC,
JSObjectGetProperty_FUNC,
JSObjectGetPropertyAtIndex_FUNC,
- JSObjectMakeArray_FUNC,
JSStringCreateWithUTF8CString_FUNC,
JSStringGetMaximumUTF8CStringSize_FUNC,
JSStringGetUTF8CString_FUNC,
JSStringRelease_FUNC,
JSValueGetType_FUNC,
- JSValueMakeBoolean_FUNC,
- JSValueMakeNumber_FUNC,
- JSValueMakeString_FUNC,
- JSValueMakeUndefined_FUNC,
JSValueToNumber_FUNC,
JSValueToStringCopy_FUNC,
soup_1cookie_1get_1name_FUNC,
@@ -95,19 +90,27 @@ typedef enum {
webkit_1policy_1decision_1ignore_FUNC,
webkit_1response_1policy_1decision_1get_1request_FUNC,
webkit_1response_1policy_1decision_1get_1response_FUNC,
+ webkit_1security_1manager_1register_1uri_1scheme_1as_1secure_FUNC,
webkit_1uri_1request_1get_1http_1headers_FUNC,
webkit_1uri_1request_1get_1uri_FUNC,
webkit_1uri_1request_1new_FUNC,
webkit_1uri_1response_1get_1content_1length_FUNC,
webkit_1uri_1response_1get_1mime_1type_FUNC,
+ webkit_1uri_1scheme_1request_1finish_FUNC,
+ webkit_1uri_1scheme_1request_1get_1uri_FUNC,
+ webkit_1uri_1scheme_1request_1get_1web_1view_FUNC,
+ webkit_1user_1content_1manager_1add_1script_FUNC,
+ webkit_1user_1content_1manager_1remove_1all_1scripts_FUNC,
+ webkit_1user_1script_1new_FUNC,
+ webkit_1user_1script_1unref_FUNC,
webkit_1web_1context_1allow_1tls_1certificate_1for_1host_FUNC,
webkit_1web_1context_1get_1cookie_1manager_FUNC,
webkit_1web_1context_1get_1default_FUNC,
+ webkit_1web_1context_1get_1security_1manager_FUNC,
webkit_1web_1context_1get_1type_FUNC,
webkit_1web_1context_1get_1website_1data_1manager_FUNC,
+ webkit_1web_1context_1register_1uri_1scheme_FUNC,
webkit_1web_1context_1set_1tls_1errors_1policy_FUNC,
- webkit_1web_1context_1set_1web_1extensions_1directory_FUNC,
- webkit_1web_1context_1set_1web_1extensions_1initialization_1user_1data_FUNC,
webkit_1web_1resource_1get_1data_FUNC,
webkit_1web_1resource_1get_1data_1finish_FUNC,
webkit_1web_1view_1can_1go_1back_FUNC,
@@ -120,6 +123,7 @@ typedef enum {
webkit_1web_1view_1get_1settings_FUNC,
webkit_1web_1view_1get_1title_FUNC,
webkit_1web_1view_1get_1uri_FUNC,
+ webkit_1web_1view_1get_1user_1content_1manager_FUNC,
webkit_1web_1view_1get_1window_1properties_FUNC,
webkit_1web_1view_1go_1back_FUNC,
webkit_1web_1view_1go_1forward_FUNC,
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
index e249737812..e797734421 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java
@@ -52,20 +52,7 @@ import org.eclipse.swt.widgets.*;
* (the exception is the webextension, because it runs as a separate process and is only loaded dynamically).
* - Try to keep all of your logic in Java and avoid writing custom C-code. (I went down this pit). Because if you
* use native code, then you have to write dynamic native code (get function pointers, cast types etc.. big pain in the ass).
- * (Webextension is again an exception).
* - Don't try to add webkit2 include flags to pkg-config, as this will tie the swt-glue code to specific webkit versions. Thou shall not do this.
- * (webextension is an exception).
- *
- * Webextension:
- * - On Webkit2, a webextension is used to provide browserfunction/javascript callback functionality. (See the whole WebkitGDBus.java business).
- * - I've initially implemented javascript execution by running javascript and then waiting in a display-loop until webkit makes a return call.
- * I then added a whole bunch of logic to avoid deadlocks.
- * In retrospec, the better approach would be to send things off via GDBus and let the webextension run the javascript synchronously.
- * But this would take another 1-2 months of implementation time and wouldn't guarantee dead-lock free behaviour as callbacks could potentailly still
- * cause deadlocks. It's an interesting thought however..
- * - Note, most GDBus tutorials talk about compiling GDBus bindings. But using them dynamically I found is much easier. See this guide:
- * http://www.cs.grinnell.edu/~rebelsky/Courses/CSC195/2013S/Outlines/
- *
*
* EVENT_HANDLING_DOC:
* - On webkit2, signals are implemented via regular gtk mechanism, hook events and pass them along as we receive them.
@@ -109,6 +96,16 @@ class WebKit extends WebBrowser {
String tlsErrorType;
boolean firstLoad = true;
+ static boolean FirstCreate = true;
+
+ /**
+ * Stores the browser which is opening a new browser window,
+ * during a WebKit {@code create} signal. This browser
+ * must be passed to a newly created browser as "related".
+ *
+ * See bug 579257.
+ */
+ private static Browser parentBrowser;
/**
* Timeout used for javascript execution / deadlock detection.
@@ -172,6 +169,9 @@ class WebKit extends WebBrowser {
static final String DOMEVENT_MOUSEOVER = "mouseover"; //$NON-NLS-1$
static final String DOMEVENT_MOUSEWHEEL = "mousewheel"; //$NON-NLS-1$
+ static final byte[] SWT_PROTOCOL = Converter.wcsToMbcs("swt", true); // $NON-NLS-1$
+ static final byte[] JSON_MIME_TYPE = Converter.wcsToMbcs("application/json", true); // $NON-NLS-1$
+
/* WebKit signal data */
static final int NOTIFY_PROGRESS = 1;
static final int NOTIFY_TITLE = 2;
@@ -195,10 +195,7 @@ class WebKit extends WebBrowser {
static final String SWT_WEBKITGTK_VERSION = "org.eclipse.swt.internal.webkitgtk.version"; //$NON-NLS-1$
/* the following Callbacks are never freed */
- static Callback Proc2, Proc3, Proc4, Proc5;
-
- /** Process key/mouse events from javascript. */
- static Callback JSDOMEventProc;
+ static Callback Proc2, Proc3, Proc4, Proc5, JSDOMEventProc, RequestProc;
/** Flag indicating whether TLS errors (like self-signed certificates) are to be ignored. */
static final boolean ignoreTls;
@@ -210,9 +207,8 @@ class WebKit extends WebBrowser {
Proc5 = new Callback (WebKit.class, "Proc", 5); //$NON-NLS-1$
new Webkit2AsyncToSync();
- WebKitExtension.init();
-
JSDOMEventProc = new Callback (WebKit.class, "JSDOMEventProc", 3); //$NON-NLS-1$
+ RequestProc = new Callback (WebKit.class, "RequestProc", 2); //$NON-NLS-1$
NativeClearSessions = () -> {
if (!WebKitGTK.LibraryLoaded) return;
@@ -255,49 +251,32 @@ class WebKit extends WebBrowser {
@Override
public void createFunction(BrowserFunction function) {
- if (!WebkitGDBus.initialized) {
- System.err.println("SWT webkit: WebkitGDBus and/or Webkit2Extension not loaded, BrowserFunction will not work." +
- "Tried to create "+ function.name);
- return;
- }
super.createFunction(function);
- String url = this.getUrl().isEmpty() ? "nullURL" : this.getUrl();
- /*
- * If the proxy to the extension has not yet been loaded, store the BrowserFunction page ID,
- * function string, and URL in a HashMap. Once the proxy to the extension is loaded, these
- * functions will be sent to and registered in the extension.
- */
- if (!WebkitGDBus.connectionToExtensionCreated) {
- WebkitGDBus.functionsPending = true;
- ArrayList<ArrayList<String>> list = new ArrayList<>();
- ArrayList<String> functionAndUrl = new ArrayList<>();
- functionAndUrl.add(0, function.functionString);
- functionAndUrl.add(1, url);
- list.add(functionAndUrl);
- ArrayList<ArrayList<String>> existing = WebkitGDBus.pendingBrowserFunctions.putIfAbsent(this.pageId, list);
- if (existing != null) {
- existing.add(functionAndUrl);
- }
- } else {
- // If the proxy to the extension is already loaded, register the function in the extension via DBus
- boolean successful = webkit_extension_modify_function(this.pageId, function.functionString, url, "register");
- if (!successful) {
- System.err.println("SWT webkit: failure registering BrowserFunction " + function.name);
- }
- }
+ updateUserScript();
}
@Override
public void destroyFunction (BrowserFunction function) {
- // Only deregister functions if the proxy to the extension has been loaded
- if (WebkitGDBus.connectionToExtensionCreated) {
- String url = this.getUrl().isEmpty() ? "nullURL" : this.getUrl();
- boolean successful = webkit_extension_modify_function(this.pageId, function.functionString, url, "deregister");
- if (!successful) {
- System.err.println("SWT webkit: failure deregistering BrowserFunction from extension " + function.name);
+ super.destroyFunction(function);
+ updateUserScript();
+ }
+
+ void updateUserScript() {
+ // Maintain a script bundle of BrowserFunctions to be injected on page navigation or reload.
+ long manager = WebKitGTK.webkit_web_view_get_user_content_manager(webView);
+ WebKitGTK.webkit_user_content_manager_remove_all_scripts(manager);
+ if (!functions.isEmpty()) {
+ StringBuilder sb = new StringBuilder();
+ for (BrowserFunction function : functions.values()) {
+ sb.append(function.functionString);
}
+ sb.append('\0');
+ byte[] scriptData = sb.toString().getBytes(StandardCharsets.UTF_8);
+ long script = WebKitGTK.webkit_user_script_new(
+ scriptData, WebKitGTK.WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START, WebKitGTK.WEBKIT_USER_CONTENT_INJECT_TOP_FRAME, 0, 0);
+ WebKitGTK.webkit_user_content_manager_add_script(manager, script);
+ WebKitGTK.webkit_user_script_unref(script);
}
- super.destroyFunction(function);
}
private static String getInternalErrorMsg () {
@@ -321,170 +300,16 @@ class WebKit extends WebBrowser {
return sw.toString();
}
- /**
- * This class deals with the WebKit extension.
- *
- * Extension is separately loaded and deals Javascript callbacks to Java.
- * Extension is needed so that Javascript can receive a return value from Java
- * (for which currently there is no api in WebkitGtk 2.18)
- */
- static class WebKitExtension {
- /** Note, if updating this, you need to change it also in webkitgtk_extension.c */
- private static final String javaScriptFunctionName = "webkit2callJava"; // $NON-NLS-1$
- private static final String webkitWebExtensionIdentifier = "webkitWebExtensionIdentifier"; // $NON-NLS-1$
- private static Callback initializeWebExtensions_callback;
-
- /** GDBusServer returned by WebkitGDBus */
- private static long dBusServer = 0;
-
- /**
- * Don't continue initialization if something failed. This allows Browser to carryout some functionality
- * even if the webextension failed to load.
- */
- private static boolean loadFailed;
-
- static String getJavaScriptFunctionName() {
- return javaScriptFunctionName;
- }
- static String getWebExtensionIdentifier() {
- return webkitWebExtensionIdentifier;
- }
- static String getJavaScriptFunctionDeclaration(long webView) {
- return "if (!window.callJava) {\n"
- + " window.callJava = function callJava(index, token, args) {\n"
- + " return " + javaScriptFunctionName + "('" + String.valueOf(webView) + "', index, token, args);\n"
- + " }\n"
- + "};\n";
- }
-
- static void init() {
- /*
- * Initialize GDBus before the extension, as the extension initialization callback at the C level
- * sends data back to SWT via GDBus. Failure to load GDBus here will result in crashes.
- * See bug 536141.
- */
- dBusServer = gdbus_init();
- if (dBusServer == 0) {
- System.err.println("SWT WebKit: error initializing DBus server, dBusServer == 0");
- }
- initializeWebExtensions_callback = new Callback(WebKitExtension.class, "initializeWebExtensions_callback", void.class, new Type [] {long.class, long.class});
- if (WebKitGTK.webkit_get_minor_version() >= 4) { // Callback exists only since 2.04
- OS.g_signal_connect (WebKitGTK.webkit_web_context_get_default(), WebKitGTK.initialize_web_extensions, initializeWebExtensions_callback.getAddress(), 0);
- }
- }
-
- /**
- * GDbus initialization can cause performance slow downs. So we int GDBus in lazy way.
- * It can be initialized upon first use of BrowserFunction.
- */
- static long gdbus_init() {
- if (WebKitGTK.webkit_get_minor_version() < 4) {
- System.err.println("SWT Webkit: Warning, You are using an old version of webkitgtk. (pre 2.4)"
- + " BrowserFunction functionality will not be available");
- return 0;
- }
-
-
- if (!loadFailed) {
- return WebkitGDBus.init();
- } else {
- return 0;
- }
- }
-
- /**
- * This callback is called to initialize webextension.
- * It is the optimum place to set extension directory and set initialization user data.
- *
- * I've experimented with loading webextension later (to see if we can get performance gains),
- * but found breakage. Webkitgtk doc says it should be loaded as early as possible and specifically best
- * to do it in this calllback.
- *
- * See documenation: WebKitWebExtension (Description)
- */
- @SuppressWarnings("unused") // Only called directly from C
- private static void initializeWebExtensions_callback (long WebKitWebContext, long user_data) {
- // 1) GDBus:
- // Normally we'd first initialize gdbus channel. But gdbus makes Browser slower and isn't always needed.
- // So WebkitGDBus is lazy-initialized, although it can be initialized here if gdbus is ever needed
- // for more than BrowserFunction, like:
- // WebkitGDBus.init(String.valueOf(uniqueID));
- // Also consider only loading gdbus if the extension initialized properly.
-
- // 2) Load Webkit Extension:
- // Webkit extensions should be in their own directory.
- String swtVersion = Library.getVersionString();
- File extension;
- try {
- extension = Library.findResource("webkitextensions" + swtVersion ,"swt-webkit2extension", true);
- if (extension == null){
- throw new UnsatisfiedLinkError("SWT Webkit could not find it's webextension");
- }
- } catch (UnsatisfiedLinkError e) {
- System.err.println("SWT Webkit.java Error: Could not find webkit extension. BrowserFunction functionality will not be available. \n"
- + "(swt version: " + swtVersion + ")" + WebKitGTK.swtWebkitGlueCodeVersion + WebKitGTK.swtWebkitGlueCodeVersionInfo);
- int [] vers = internalGetWebkitVersion();
- System.err.println(String.format("WebKit2Gtk version %s.%s.%s", vers[0], vers[1], vers[2]));
- System.err.println(getInternalErrorMsg());
- loadFailed = true;
- return;
- }
-
- String extensionsFolder = extension.getParent();
- /* Dev note:
- * As per
- * - WebkitSrc: WebKitExtensionManager.cpp,
- * - IRC discussion with annulen
- * you cannot load the webextension GModule directly, (webkitgtk 2.18). You can only specify directory and user data.
- * So we need to treat this '.so' in a special way.
- * (as a note, the webprocess would have to load the gmodule).
- */
- WebKitGTK.webkit_web_context_set_web_extensions_directory(WebKitGTK.webkit_web_context_get_default(), Converter.wcsToMbcs (extensionsFolder, true));
- long clientAddress = OS.g_dbus_server_get_client_address(dBusServer);
- String clientAddressJava = Converter.cCharPtrToJavaString(clientAddress, false);
- long gvariantUserData = OS.g_variant_new_string(clientAddress);
- WebKitGTK.webkit_web_context_set_web_extensions_initialization_user_data(WebKitGTK.webkit_web_context_get_default(), gvariantUserData);
- }
-
- /**
- * @param cb_args Raw callback arguments by function.
- */
- static Object webkit2callJavaCallback(Object [] cb_args) {
- assert cb_args.length == 4;
- Object returnValue = null;
- Long webViewLocal = (Double.valueOf((String) cb_args[0])).longValue();
- Browser browser = FindBrowser((long ) webViewLocal.longValue());
- Integer functionIndex = ((Double) cb_args[1]).intValue();
- String token = (String) cb_args[2];
-
- BrowserFunction function = browser.webBrowser.functions.get(functionIndex);
- if (function == null) {
- System.err.println("SWT Webkit Error: Failed to find function with index: " + functionIndex);
- return null;
- }
- if (!function.token.equals(token)) {
- System.err.println("SWT Webkit Error: token mismatch for function with index: " + functionIndex);
- return null;
- }
- try {
- // Call user code. Exceptions can occur.
- nonBlockingEvaluate++;
- Object [] user_args = (Object []) cb_args[3];
- returnValue = function.function(user_args);
- } catch (Exception e ) {
- // - Something went wrong in user code.
- System.err.println("SWT Webkit: Exception occured in user code of function: " + function.name);
- returnValue = WebBrowser.CreateErrorString (e.getLocalizedMessage ());
- } finally {
- nonBlockingEvaluate--;
- }
- return returnValue;
- }
- }
-
@Override
String getJavaCallDeclaration() {
- return WebKitExtension.getJavaScriptFunctionDeclaration(webView);
+ // callJava does a synchronous XMLHttpRequest, which is handled by RequestProc.
+ return "if (!window.callJava) { window.callJava = function(index, token, args) {\n"
+ + "var xhr = new XMLHttpRequest();\n"
+ + "var uri = 'swt://browserfunction/' + index + '/' + token + '?' + encodeURIComponent(JSON.stringify(args));\n"
+ + "xhr.open('POST', uri, false);\n"
+ + "xhr.send(null);\n"
+ + "return JSON.parse(xhr.responseText);\n"
+ + "}}\n";
}
/**
@@ -601,6 +426,54 @@ static long JSDOMEventProc (long arg0, long event, long user_data) {
return 0;
}
+static long RequestProc (long request, long user_data) {
+ // Custom protocol handler (swt://) for BrowserFunction callbacks.
+ // Note that a response must be sent regardless of any errors, otherwise the caller will hang.
+ String response = "null";
+
+ long webView = WebKitGTK.webkit_uri_scheme_request_get_web_view(request);
+ Browser browser = FindBrowser(webView);
+ if (browser != null) {
+ BrowserFunction function = null;
+ Object[] args = null;
+
+ long uriPtr = WebKitGTK.webkit_uri_scheme_request_get_uri(request);
+ String uriStr = Converter.cCharPtrToJavaString(uriPtr, false);
+ try {
+ URI uri = new URI(uriStr);
+ String[] parts = uri.getPath().split("/");
+ int index = Integer.parseInt(parts[1]);
+ String token = parts[2];
+
+ WebKit webkit = (WebKit)browser.webBrowser;
+ function = webkit.functions.get(index);
+ if (function != null && !function.token.equals(token)) {
+ function = null;
+ }
+
+ args = (Object[]) JSON.parse(uri.getQuery());
+ } catch (URISyntaxException | IllegalArgumentException | IndexOutOfBoundsException | ClassCastException e) {
+ }
+
+ if (function != null) {
+ Object result;
+ try {
+ result = function.function(args);
+ } catch (Exception e) {
+ result = WebBrowser.CreateErrorString(e.getLocalizedMessage());
+ }
+ response = JSON.stringify(result);
+ }
+ }
+
+ long[] outBytes = new long[1];
+ long dataPtr = OS.g_utf16_to_utf8(response.toCharArray(), response.length(), null, outBytes, null);
+ long stream = OS.g_memory_input_stream_new_from_data(dataPtr, outBytes[0], OS.addressof_g_free());
+ WebKitGTK.webkit_uri_scheme_request_finish(request, stream, outBytes[0], JSON_MIME_TYPE);
+ OS.g_object_unref(stream);
+ return 0;
+}
+
static long Proc (long handle, long user_data) {
long webView = handle;
@@ -767,10 +640,18 @@ public void create (Composite parent, int style) {
*/
Webkit2AsyncToSync.setCookieBrowser(browser);
+ if (FirstCreate) {
+ FirstCreate = false;
+ // Register the swt:// custom protocol for BrowserFunction calls via XMLHttpRequest
+ long context = WebKitGTK.webkit_web_context_get_default();
+ WebKitGTK.webkit_web_context_register_uri_scheme(context, SWT_PROTOCOL, RequestProc.getAddress(), 0, 0);
+ long security = WebKitGTK.webkit_web_context_get_security_manager(context);
+ WebKitGTK.webkit_security_manager_register_uri_scheme_as_secure(security, SWT_PROTOCOL);
+ }
Composite parentShell = parent.getParent();
- Browser parentBrowser = null;
- if (parentShell != null) {
+ Browser parentBrowser = WebKit.parentBrowser;
+ if (parentBrowser == null && parentShell != null) {
Control[] children = parentShell.getChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof Browser) {
@@ -996,46 +877,6 @@ void nonBlockingExecute(String script) {
}
}
-/**
- * Modifies a BrowserFunction in the web extension. This method can be used to register/deregister BrowserFunctions
- * in the web extension, so that those BrowserFunctions are executed upon triggering of the object_cleared callback (in
- * the extension, not in Java).
- *
- * This function will return true if: the operation succeeds synchronously, or if the synchronous call timed out and an
- * asynchronous call was performed instead. All other cases will return false.
- *
- * Supported actions: "register" and "deregister"
- *
- * @param pageId the page ID of the WebKit instance/web page
- * @param function the function string
- * @param url the URL
- * @param action the action being performed on the function, which will be used to form the DBus method name.
- * @return true if the action succeeded (or was performed asynchronously), false if it failed
- */
-private boolean webkit_extension_modify_function (long pageId, String function, String url, String action){
- long[] args = { OS.g_variant_new_uint64(pageId),
- OS.g_variant_new_string (Converter.javaStringToCString(function)),
- OS.g_variant_new_string (Converter.javaStringToCString(url))};
- final long argsTuple = OS.g_variant_new_tuple(args, args.length);
- if (argsTuple == 0) return false;
- String dbusMethodName = "webkitgtk_extension_" + action + "_function";
- Object returnVal = WebkitGDBus.callExtensionSync(argsTuple, dbusMethodName);
- if (returnVal instanceof Boolean) {
- return (Boolean) returnVal;
- } else if (returnVal instanceof String) {
- String returnString = (String) returnVal;
- /*
- * Call the extension asynchronously if a synchronous call times out.
- * Note: this is a pretty rare case, and usually only happens when running test cases.
- * See bug 536141.
- */
- if ("timeout".equals(returnString)) {
- return WebkitGDBus.callExtensionAsync(argsTuple, dbusMethodName);
- }
- }
- return false;
-}
-
@Override
public boolean execute (String script) {
if (!isJavascriptEnabled()) {
@@ -1165,27 +1006,6 @@ private static class Webkit2AsyncToSync {
* SWT implementation.
*
* If in doubt, you should use nonBlockingExecute() where possible :-).
- *
- * TODO_SOMEDAY:
- * - Instead of async js execution and waiting for return value, it might be
- * better to use gdbus, connect to webextension and execute JS synchronously.
- * See: https://blogs.igalia.com/carlosgc/2013/09/10/webkit2gtk-web-process-extensions/
- * 'Extending JavaScript'
- * Pros:
- * - less likely deadlocks would occur due to developer error/not being careful.
- * - js execution can work in synchronous callbacks from webkit.
- * Cons:
- * - High implementation cost/complexity.
- * - Unexpected errors/behaviour due to GDBus timeouts.
- * Proof of concept:
- * https://git.eclipse.org/r/#/c/23416/16/bundles/org.eclipse.swt/Eclipse+SWT+WebKit/gtk/library/webkit_extension.c
- * > 'webkit_extension_execute_script'
- * Tennative structure:
- * - Webextension should create gdbus server, make & communicate UniqueID (pid) to main proc
- * - main proc should make a note of webextension's name+uniqueID
- * - implement mechanism for packaging Java objects into gvariants, (see WebkitGDBus.java),
- * - call webextension over gdbus, parse return value.
- *
*/
static Object runjavascript(String script, Browser browser, long webView) {
if (nonBlockingEvaluate > 0) {
@@ -1364,7 +1184,7 @@ private static class Webkit2AsyncToSync {
* triggers.
*/
Consumer<Integer> asyncFunc = (callbackID) -> WebKitGTK.webkit_cookie_manager_get_cookies(cookieManager, uri, 0,
- getCookie_callback.getAddress(), WebkitGDBus.convertJavaToGVariant(new Object [] {cookieName, callbackID}));
+ getCookie_callback.getAddress(), GDBus.convertJavaToGVariant(new Object [] {cookieName, callbackID}));
Webkit2AsyncReturnObj retObj = execAsyncAndWaitForReturn(cookieBrowser, asyncFunc, " getCookie() was called");
if (retObj.swtAsyncTimeout) {
@@ -1376,7 +1196,7 @@ private static class Webkit2AsyncToSync {
@SuppressWarnings("unused") // Callback only called only by C directly
private static void getCookie_callback(long cookieManager, long result, long user_data) {
- Object resultObject = WebkitGDBus.convertGVariantToJava(user_data);
+ Object resultObject = GDBus.convertGVariantToJava(user_data);
// We are expecting a GVariant tuple, anything else means something went wrong
if (resultObject instanceof Object []) {
@@ -2325,10 +2145,12 @@ long webkit_create_web_view (long web_view, long frame) {
};
try {
nonBlockingEvaluate++; // running evaluate() inside openWindowListener and waiting for return leads to deadlock. Bug 512001
+ parentBrowser = browser;
fireOpenWindowListeners.run();// Permit evaluate()/execute() to execute scripts in listener, but do not provide return value.
} catch (Exception e) {
throw e; // rethrow execption if thrown, but decrement counter first.
} finally {
+ parentBrowser = null;
nonBlockingEvaluate--;
}
Browser browser = null;
@@ -2803,38 +2625,6 @@ private void webkit_settings_set(byte [] property, int value) {
OS.g_object_set(settings, property, value, 0);
}
-long convertToJS (long ctx, Object value) {
- if (value == null) {
- return WebKitGTK.JSValueMakeUndefined (ctx);
- }
- if (value instanceof String) {
- byte[] bytes = ((String)value + '\0').getBytes (StandardCharsets.UTF_8); //$NON-NLS-1$
- long stringRef = WebKitGTK.JSStringCreateWithUTF8CString (bytes);
- long result = WebKitGTK.JSValueMakeString (ctx, stringRef);
- WebKitGTK.JSStringRelease (stringRef);
- return result;
- }
- if (value instanceof Boolean) {
- return WebKitGTK.JSValueMakeBoolean (ctx, ((Boolean)value).booleanValue () ? 1 : 0);
- }
- if (value instanceof Number) {
- return WebKitGTK.JSValueMakeNumber (ctx, ((Number)value).doubleValue ());
- }
- if (value instanceof Object[]) {
- Object[] arrayValue = (Object[]) value;
- int length = arrayValue.length;
- long [] arguments = new long [length];
- for (int i = 0; i < length; i++) {
- Object javaObject = arrayValue[i];
- long jsObject = convertToJS (ctx, javaObject);
- arguments[i] = jsObject;
- }
- return WebKitGTK.JSObjectMakeArray (ctx, length, arguments, null);
- }
- SWT.error (SWT.ERROR_INVALID_RETURN_VALUE);
- return 0;
-}
-
static Object convertToJava (long ctx, long value) {
int type = WebKitGTK.JSValueGetType (ctx, value);
switch (type) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebkitGDBus.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebkitGDBus.java
deleted file mode 100644
index ef293be750..0000000000
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebkitGDBus.java
+++ /dev/null
@@ -1,666 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2017, 2022 Red Hat and others. All rights reserved.
- * The contents of this file are made available under the terms
- * of the GNU Lesser General Public License (LGPL) Version 2.1 that
- * accompanies this distribution (lgpl-v21.txt). The LGPL is also
- * available at http://www.gnu.org/licenses/lgpl.html. If the version
- * of the LGPL at http://www.gnu.org is different to the version of
- * the LGPL accompanying this distribution and there is any conflict
- * between the two license versions, the terms of the LGPL accompanying
- * this distribution shall govern.
- *
- * Contributors:
- * Red Hat - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.swt.browser;
-
-import java.util.*;
-import java.util.Map.*;
-
-import org.eclipse.swt.*;
-import org.eclipse.swt.internal.*;
-import org.eclipse.swt.internal.gtk.*;
-import org.eclipse.swt.widgets.*;
-
-/**
- * Logic for Webkit to interact with it's Webkit extension via GDBus.
- *
- * While this class supports quite a bit of GDBus and gvariant support, it is by no means a complete
- * implementation and it's tailored to support Java to Javascript conversion. (E.g all Numbers are converted to Double).
- * If this is ever to be used outside of Webkit, then care must be taken to deal with
- * cases that are not currently implemented/used. See: WebKitGTK.java 'TYPE NOTES'
- *
- * For hygiene purposes, GVariant types should not be leaving this class. Convert on the way in/out.
- *
- * @category gdbus
- */
-class WebkitGDBus {
- /*
- * If any of the GDBus names/paths/interfaces need to be changed, then they also need to be changed
- * in the extension (webkitgtk_extension.c).
- */
-
- /* WEBKITGDBUS_DBUS_NAME isn't actually used but is here for informative purposes */
- @SuppressWarnings("unused")
- private static final String WEBKITGDBUS_DBUS_NAME = "org.eclipse.swt";
- private static final byte [] WEBKITGDBUS_OBJECT_PATH = Converter.javaStringToCString("/org/eclipse/swt/gdbus");
- private static final String WEBKITGDBUS_INTERFACE_NAME_JAVA = "org.eclipse.swt.gdbusInterface";
- private static final byte [] WEBKITGDBUS_INTERFACE_NAME = Converter.javaStringToCString("org.eclipse.swt.gdbusInterface");
-
- /* Extension connection details, in byte [] form */
- private static final byte [] EXTENSION_DBUS_NAME = Converter.javaStringToCString("org.eclipse.swt.webkitgtk_extension");
- private static final byte [] EXTENSION_OBJECT_PATH = Converter.javaStringToCString("/org/eclipse/swt/webkitgtk_extension/gdbus");
- private static final byte [] EXTENSION_INTERFACE_NAME = Converter.javaStringToCString("org.eclipse.swt.webkitgtk_extension.gdbusInterface");
-
- /** Extension GDBusServer client address */
- private static String EXTENSION_DBUS_SERVER_CLIENT_ADDRESS;
-
- /* Accepted GDBus methods */
- private static final String webkit2callJava = WebKit.WebKitExtension.getJavaScriptFunctionName();
- private static final String webkitWebExtensionIdentifier = WebKit.WebKitExtension.getWebExtensionIdentifier();
-
- /* Connections */
- /** GDBusConnection from the web extension */
- static long connectionFromExtension;
- /** GDBusConnection to the web extension */
- static long connectionToExtension;
- /** A field that is set to true if the proxy connection has been established, false otherwise. */
- static boolean connectionToExtensionCreated;
-
- /* Server related objects */
- /** GDBusServer for the main SWT process */
- private static long gDBusServer = 0;
- /** GDBusAuthObserver for the server */
- private static long authObserver = 0;
- /** GUID of the GDBusServer */
- private static long guid = 0;
-
- /** Display this GDBus class is "attached" to */
- static Display display;
-
-
- // BrowserFunction logic
- /** Set to true if there are <code>BrowserFunction</code> objects waiting to be registered with the web extension.*/
- static boolean functionsPending;
- /**
- * HashMap that stores any BrowserFunctions which have been created but not yet registered with the web extension.
- * These functions will be registered with the web extension as soon as the proxy to the extension is set up.
- *
- * The format of the HashMap is (page ID, list of function string and URL).
- */
- static HashMap<Long, ArrayList<ArrayList<String>>> pendingBrowserFunctions = new HashMap<>();
-
-
- /**
- * Interface is read/parsed at run time. No compilation with gdbus-code-gen necessary.
- *
- * Note,
- * - When calling a method via g_dbus_proxy_call_sync(..g_variant params..),
- * the g_variant that describes parameters should only mirror incoming parameters.
- * Each type is a separate argument.
- * e.g:
- * g_variant xml:
- * "(si)", "string", 42 .. arg type='s'
- * .. arg type='i'
- *
- * - Nested parameters need to have a 2nd bracket around them.
- * e.g:
- * g_variant xml:
- * "((r)i)", *gvariant, 42 .. arg type='r'
- * .. arg type='i'
- *
- * - '@' is a pointer to a gvariant. so '@r' is a pointer to nested type, i.e *gvariant
- *
- * To understand the mappings, it's good to understand DBus and GVariant's syntax:
- * https://dbus.freedesktop.org/doc/dbus-specification.html#idm423
- * https://developer.gnome.org/glib/stable/glib-GVariantType.html
- *
- * Be mindful about only using supported DBUS_TYPE_* , as convert* methods might fail otherwise.
- * Alternatively, modify convert* methods.
- */
- private static final byte [] WEBKITGDBUS_INTROSPECTION_XML = Converter.javaStringToCString(
- "<node>"
- + " <interface name='" + WEBKITGDBUS_INTERFACE_NAME_JAVA + "'>"
- + " <method name='" + webkit2callJava + "'>"
- + " <arg type='"+ OS.DBUS_TYPE_STRING + "' name='webViewPtr' direction='in'/>"
- + " <arg type='"+ OS.DBUS_TYPE_DOUBLE + "' name='index' direction='in'/>"
- + " <arg type='"+ OS.DBUS_TYPE_STRING + "' name='token' direction='in'/>"
- + " <arg type='" + OS.DBUS_TYPE_SINGLE_COMPLETE + "' name='arguments' direction='in'/>"
- + " <arg type='" + OS.DBUS_TYPE_SINGLE_COMPLETE + "' name='result' direction='out'/>"
- + " </method>"
- + " <method name='" + webkitWebExtensionIdentifier + "'>"
- + " <arg type='"+ OS.DBUS_TYPE_STRING + "' name='webExtensionServerAddress' direction='in'/>"
- + " <arg type='"+ OS.DBUS_TYPE_STRUCT_ARRAY_BROWSER_FUNCS + "' name='result' direction='out'/>"
- + " </method>"
- + " </interface>"
- + "</node>");
-
- /**
- * GDBus/DBus doesn't have a notion of Null.
- * To get around this, we use magic numbers to represent special cases.
- * Currently this is specific to Webkit to deal with Javascript data type conversions.
- * @category gdbus */
- private static final byte SWT_DBUS_MAGIC_NUMBER_EMPTY_ARRAY = 101;
- /** @category gdbus */
- private static final byte SWT_DBUS_MAGIC_NUMBER_NULL = 48;
-
-
- /** Callback for GDBus method handling */
- private static Callback handleMethodCB;
- /** Callback for incoming connections to WebkitGDBus' server */
- private static Callback newConnectionCB;
- /** Callback for creating a new connection to the web extension */
- private static Callback newConnectionToExtensionCB;
- /** Callback for authenticating connections to WebkitGDBus' server */
- private static Callback authenticatePeerCB;
- /** Callback for asynchronous proxy calls to the extension */
- private static Callback callExtensionAsyncCB;
-
- static {
- handleMethodCB = new Callback (WebkitGDBus.class, "handleMethodCB", 8); //$NON-NLS-1$
- callExtensionAsyncCB = new Callback (WebkitGDBus.class, "callExtensionAsyncCB", 3); //$NON-NLS-1$
- newConnectionCB = new Callback (WebkitGDBus.class, "newConnectionCB", 3); //$NON-NLS-1$
- newConnectionToExtensionCB = new Callback (WebkitGDBus.class, "newConnectionToExtensionCB", 3); //$NON-NLS-1$
- authenticatePeerCB = new Callback (WebkitGDBus.class, "authenticatePeerCB", 4); //$NON-NLS-1$
- }
-
- /** True iff the GDBusServer has been initialized */
- static boolean initialized;
- /** True iff this class has been attached to a Display */
- static boolean attachedToDisplay;
-
- /** This method is in an internal class and is not intended to be referenced by clients. */
- static long init () {
- if (initialized) {
- return gDBusServer;
- }
- initialized = true;
-
- // Generate address and GUID
- long address = construct_server_address();
- authObserver = OS.g_dbus_auth_observer_new();
- guid = OS.g_dbus_generate_guid();
-
- // Create server
- long [] error = new long [1];
- gDBusServer = OS.g_dbus_server_new_sync(address, OS.G_DBUS_SERVER_FLAGS_NONE, guid, authObserver, 0, error);
-
- // Connect authentication and incoming connections signals to the newly created server, and start it
- if (gDBusServer != 0) {
- OS.g_signal_connect(gDBusServer, OS.new_connection, newConnectionCB.getAddress(), 0);
- OS.g_signal_connect(authObserver, OS.authorize_authenticated_peer, authenticatePeerCB.getAddress(), 0);
- OS.g_dbus_server_start(gDBusServer);
- } else {
- System.err.println("SWT WebKitGDBus: error creating DBus server " + Display.extractFreeGError(error[0]));
- }
- return gDBusServer;
- }
-
- /**
- * Sets the Display for this class. This allows WebkitGDBus to attach its servers and related objects
- * to the provided Display. When the Display is disposed, it will will release the GDBus related
- * resources.
- *
- * @param displayToSet the Display to set
- */
- static void setDisplay (Display displayToSet) {
- if (!attachedToDisplay) {
- display = displayToSet;
-
- /*
- * Add the GDBusServer, GDBusAuthObserver, and GUID to the Display.
- * Note that we don't add the connections yet, because they likely
- * don't exist. Those are added in callbacks as they come in.
- */
- if (gDBusServer != 0) display.dBusServers.add(gDBusServer);
- if (authObserver != 0) display.dBusAuthObservers.add(authObserver);
- if (guid != 0) display.dBusGUIDS.add(guid);
- attachedToDisplay = true;
- }
- }
-
- /**
- * Constructs an address at which the GDBus server for the SWT main process
- * can be reached.
- *
- * @return a pointer to the address
- */
- private static long construct_server_address () {
- // On Linux, the address required is used for as an abstract path. If abstract path is not supported
- // one must create & manage temporary directories. See Bug562443.
- byte [] address = Converter.wcsToMbcs("unix:tmpdir=/tmp/SWT-GDBusServer", true);
- long addressPtr = OS.g_malloc(address.length);
- C.memmove(addressPtr, address, address.length);
-
- return addressPtr;
- }
-
- /**
- * This is called when a client call one of the GDBus methods.
- *
- * Developer note:
- * This method can be reached directly from GDBus cmd utility:
- * gdbus call --session --dest org.eclipse.swt<UNIQUE_ID> --object-path /org/eclipse/swt/gdbus --method org.eclipse.swt.gdbusInterface.HelloWorld
- * where as you tab complete, you append the UNIQUE_ID.
- *
- * @param connection GDBusConnection
- * @param sender const gchar
- * @param object_path const gchar
- * @param interface_name const gchar
- * @param method_name const gchar
- * @param gvar_parameters GVariant
- * @param invocation GDBusMethodInvocation
- * @param user_data gpointer
- * @return
- */
- @SuppressWarnings("unused") // callback not directly called by SWT
- private static long handleMethodCB (
- long connection, long sender,
- long object_path, long interface_name,
- long method_name, long gvar_parameters,
- long invocation, long user_data) {
-
- String java_method_name = Converter.cCharPtrToJavaString(method_name, false);
- Object result = null;
- if (java_method_name != null) {
- if (java_method_name.equals(webkit2callJava)) {
- try {
- Object [] java_parameters = (Object []) convertGVariantToJava(gvar_parameters);
- result = WebKit.WebKitExtension.webkit2callJavaCallback(java_parameters);
- } catch (Exception e) {
- // gdbus should always return to prevent extension from hanging.
- result = (String) WebBrowser.CreateErrorString (e.getLocalizedMessage ());
- System.err.println("SWT WebkitGDBus: Exception occured in Webkit2 callback logic.");
- }
- } else if (java_method_name.equals(webkitWebExtensionIdentifier)) {
- Object [] serverAddress = (Object []) convertGVariantToJava(gvar_parameters);
- if (serverAddress[0] instanceof String) {
- EXTENSION_DBUS_SERVER_CLIENT_ADDRESS = (String) serverAddress[0];
- // Connect to the extension's server by creating a connection asynchronously
- createConnectionToExtension();
- /*
- * Return any pending BrowserFunctions that were created before WebkitGDBus
- * was initialized.
- */
- invokeReturnValueExtensionIdentifier(pendingBrowserFunctions, invocation);
- } else {
- System.err.println("SWT WebkitGDBus: error in web extension identification process."
- + " BrowserFunction may not work.");
- }
- return 0;
- }
- } else {
- result = (String) "SWT WebkitGDBus: GDBus called an unknown method?";
- System.err.println("SWT WebkitGDBus: Received a call from an unknown method: " + java_method_name);
- }
- invokeReturnValue(result, invocation);
- return 0;
- }
-
- @SuppressWarnings("unused") // callback not directly called by SWT
- private static long callExtensionAsyncCB (long source_object, long result, long user_data) {
- long [] error = new long [1];
- long gVariantResult = OS.g_dbus_connection_call_finish (connectionToExtension, result, error);
- if (error[0] != 0) {
- String msg = Display.extractFreeGError(error[0]);
- System.err.println("SWT WebkitGDBus: there was an error executing something asynchronously with the extension (Java callback).");
- System.err.println("SWT WebkitGDBus: the error message provided is " + msg);
- }
- OS.g_variant_unref(gVariantResult);
- return 0;
- }
-
- @SuppressWarnings("unused") // callback not directly called by SWT
- private static long authenticatePeerCB (long observer, long stream, long credentials, long user_data) {
- boolean authorized = false;
- if (credentials != 0) {
- long[] error = new long [1];
- long ownCredentials = OS.g_credentials_new();
- authorized = OS.g_credentials_is_same_user(credentials, ownCredentials, error);
- if (error[0] != 0) {
- String msg = Display.extractFreeGError(error[0]);
- System.err.println("SWT WebkitGDBus: error authenticating client connection to server " + msg);
- }
- OS.g_object_unref(ownCredentials);
- }
- return authorized ? 1 : 0;
- }
-
- @SuppressWarnings("unused") // callback not directly called by SWT
- private static long newConnectionCB (long server, long connection, long user_data) {
- long gdBusNodeInfo;
- long [] error = new long [1];
- gdBusNodeInfo = OS.g_dbus_node_info_new_for_xml(WEBKITGDBUS_INTROSPECTION_XML, error);
- if (gdBusNodeInfo == 0 || error[0] != 0) {
- System.err.println("SWT WebkitGDBus: failed to get introspection data");
- }
- assert gdBusNodeInfo != 0 : "SWT WebKitGDBus: introspection data should not be 0";
-
- long interface_info = OS.g_dbus_node_info_lookup_interface(gdBusNodeInfo, WEBKITGDBUS_INTERFACE_NAME);
- long[] vtable = { handleMethodCB.getAddress(), 0, 0 };
-
- OS.g_dbus_connection_register_object(
- connection,
- WEBKITGDBUS_OBJECT_PATH,
- interface_info,
- vtable,
- 0, // user_data
- 0, // user_data_free_func
- error);
-
- if (error[0] != 0) {
- System.err.println("SWT WebKitGDBus: failed to register object: " + WEBKITGDBUS_OBJECT_PATH);
- return 0;
- }
-
- // Ref the connection and add it to the Display's list of connections
- connectionFromExtension = OS.g_object_ref(connection);
- if (attachedToDisplay && display != null) {
- if (!display.dBusConnections.contains(connection)) display.dBusConnections.add(connectionFromExtension);
- }
- return 1;
- }
-
- @SuppressWarnings("unused") // callback not directly called by SWT
- private static long newConnectionToExtensionCB (long sourceObject, long result, long user_data) {
- long [] error = new long [1];
- connectionToExtension = OS.g_dbus_connection_new_for_address_finish(result, error);
- if (error[0] != 0) {
- System.err.println("SWT WebKitGDBus: error finishing connection: " + Display.extractFreeGError(error[0]));
- return 0;
- } else {
- connectionToExtensionCreated = true;
- }
-
- // Add the connections to the Display's list of connections
- if (attachedToDisplay && display != null) {
- if (!display.dBusConnections.contains(connectionToExtension)) display.dBusConnections.add(connectionToExtension);
- }
- return 0;
- }
-
- /**
- * Returns a GVariant to the DBus invocation of the extension identifier method. When the extension
- * is initialized it sends a DBus message to the SWT webkit instance. As a return value, the SWT webkit
- * instance sends any BrowserFunctions that have been registered. If no functions have been registered,
- * an "empty" function with a page ID of -1 is sent.
- *
- * @param map the HashMap of BrowserFunctions waiting to be registered in the extension, or null
- * if you'd like to explicitly send an empty function signature
- * @param invocation the GDBus invocation to return the value on
- */
- private static void invokeReturnValueExtensionIdentifier (HashMap<Long, ArrayList<ArrayList<String>>> map,
- long invocation) {
- long resultGVariant;
- long builder;
- long type = OS.g_variant_type_new(OS.G_VARIANT_TYPE_ARRAY_BROWSER_FUNCS);
- builder = OS.g_variant_builder_new(type);
- if (builder == 0) return;
- Object [] tupleArray = new Object[3];
- boolean sendEmptyFunction;
- if (map == null) {
- sendEmptyFunction = true;
- } else {
- sendEmptyFunction = map.isEmpty() && !functionsPending;
- }
- /*
- * No functions to register, send a page ID of -1 and empty strings.
- */
- if (sendEmptyFunction) {
- tupleArray[0] = (long)-1;
- tupleArray[1] = "";
- tupleArray[2] = "";
- long tupleGVariant = convertJavaToGVariant(tupleArray);
- if (tupleGVariant != 0) {
- OS.g_variant_builder_add_value(builder, tupleGVariant);
- } else {
- System.err.println("SWT WebKitGDBus: error creating empty BrowserFunction GVariant tuple, skipping.");
- }
- } else {
- for (Entry<Long, ArrayList<ArrayList<String>>> entry : map.entrySet()) {
- ArrayList<ArrayList<String>> list = entry.getValue();
- if (list != null) {
- for (ArrayList<String> stringList : list) {
- Object [] stringArray = stringList.toArray();
- if (stringArray.length > 2) {
- System.err.println("SWT WebKitGDBus: String array with BrowserFunction and URL should never have"
- + "more than 2 Strings");
- }
- tupleArray[0] = entry.getKey();
- System.arraycopy(stringArray, 0, tupleArray, 1, 2);
- long tupleGVariant = convertJavaToGVariant(tupleArray);
- if (tupleGVariant != 0) {
- OS.g_variant_builder_add_value(builder, tupleGVariant);
- } else {
- System.err.println("SWT WebKitGDBus: error creating BrowserFunction GVariant tuple, skipping.");
- }
- }
- }
- }
- }
- resultGVariant = OS.g_variant_builder_end(builder);
- String typeString = Converter.cCharPtrToJavaString(OS.g_variant_get_type_string(resultGVariant), false);
- if (!OS.DBUS_TYPE_STRUCT_ARRAY_BROWSER_FUNCS.equals(typeString)) {
- System.err.println("SWT WebKitGDBus: an error packaging the GVariant occurred: type mismatch.");
- }
- long [] variants = {resultGVariant};
- long finalGVariant = OS.g_variant_new_tuple(variants, 1);
- OS.g_dbus_method_invocation_return_value(invocation, finalGVariant);
- OS.g_variant_builder_unref(builder);
- OS.g_variant_type_free(type);
- }
-
- private static void invokeReturnValue (Object result, long invocation) {
- long resultGVariant = 0;
- try {
- resultGVariant = convertJavaToGVariant(new Object [] {result}); // Result has to be a tuple.
- } catch (SWTException e) {
- // gdbus should always return to prevent extension from hanging.
- String errMsg = (String) WebBrowser.CreateErrorString (e.getLocalizedMessage ());
- resultGVariant = convertJavaToGVariant(new Object [] {errMsg});
- }
- OS.g_dbus_method_invocation_return_value(invocation, resultGVariant);
- }
-
- /**
- * Asynchronously initializes a GDBusConnection to the web extension. Connection process
- * will be confirmed when the newConnectionToExtension callback is called.
- */
- private static void createConnectionToExtension() {
- byte [] address = Converter.javaStringToCString(EXTENSION_DBUS_SERVER_CLIENT_ADDRESS);
- long [] error = new long [1];
- // Create connection asynchronously to avoid deadlock issues
- OS.g_dbus_connection_new_for_address (address, OS.G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
- 0, 0, newConnectionToExtensionCB.getAddress(), 0);
-
- if (error[0] != 0) {
- System.err.println("SWT WebkitGDBus: error creating connection to the extension "
- + Display.extractFreeGError(error[0]));
- }
- }
-
- /**
- * Calls the web extension synchronously. Returns true if the operation succeeded, and false
- * otherwise (or if the operation times out).
- *
- * @param params a pointer to the GVariant containing the parameters
- * @param methodName a String representing the DBus method name in the extension
- * @return an Object representing the return value from DBus in boolean form
- */
- static Object callExtensionSync (long params, String methodName) {
- long [] error = new long [1]; // GError **
- long gVariant = OS.g_dbus_connection_call_sync(connectionToExtension, EXTENSION_DBUS_NAME, EXTENSION_OBJECT_PATH,
- EXTENSION_INTERFACE_NAME, Converter.javaStringToCString(methodName), params,
- 0, OS.G_DBUS_CALL_FLAGS_NO_AUTO_START, 1000, 0, error);
- if (error[0] != 0) {
- String msg = Display.extractFreeGError(error[0]);
- /*
- * Don't print console warnings for timeout errors, as we can handle these ourselves.
- * Note, most timeout errors happen only when running test cases, not during "normal" use.
- */
- if (msg != null && (!msg.contains("Timeout") && !msg.contains("timeout"))) {
- System.err.println("SWT WebKitGDBus: there was an error executing something synchronously with the extension.");
- System.err.println("SWT WebKitGDBus: the error message is: " + msg);
- return (Object) false;
- }
- return (Object) "timeout";
- }
- Object resultObject = gVariant != 0 ? convertGVariantToJava(gVariant) : (Object) false;
- // Sometimes we get back tuples from GDBus, which get converted into Object arrays. In this case
- // we only care about the first value, since the extension never returns anything more than that.
- if (resultObject instanceof Object[]) {
- return ((Object []) resultObject)[0];
- }
- return resultObject;
- }
-
- /**
- * Calls the web extension asynchronously. Note, this method returning true does not
- * guarantee the operation's success, it only means no errors occurred.
- *
- * @param params a pointer to the GVariant containing the parameters
- * @param methodName a String representing the DBus method name in the extension
- * @return true if the extension was called without errors, false otherwise
- */
- static boolean callExtensionAsync (long params, String methodName) {
- long [] error = new long [1]; // GError **
- OS.g_dbus_connection_call(connectionToExtension, EXTENSION_DBUS_NAME, EXTENSION_OBJECT_PATH,
- EXTENSION_INTERFACE_NAME, Converter.javaStringToCString(methodName), params,
- 0, OS.G_DBUS_CALL_FLAGS_NO_AUTO_START, 1000, 0, callExtensionAsyncCB.getAddress(), 0);
- if (error[0] != 0) {
- String msg = Display.extractFreeGError(error[0]);
- System.err.println("SWT WebKitGDBus: there was an error executing something asynchronously "
- + "with the extension.");
- System.err.println("SWT WebKitGDBus: the error message is: " + msg);
- return false;
- }
- return true;
- }
-
- /* TYPE NOTES
- *
- * GDBus doesn't support all the types that we need. I used encoded 'byte' to translate some types.
- *
- * - 'null' is not supported. I thought to potentially use 'maybe' types, but they imply a possible NULL of a certain type, but not null itself.
- * so I use 'byte=48' (meaning '0' in ASCII) to denote null.
- *
- * - Empty arrays/structs are not supported by gdbus.
- * "Container types ... Empty structures are not allowed; there must be at least one type code between the parentheses"
- * src: https://dbus.freedesktop.org/doc/dbus-specification.html
- * I used byte=101 (meaning 'e' in ASCII) to denote empty array.
- *
- * In Javascript all Number types seem to be 'double', (int/float/double/short -> Double). So we convert everything into double accordingly.
- *
- * DBus Type info: https://dbus.freedesktop.org/doc/dbus-specification.html#idm423
- * GDBus Type info: https://developer.gnome.org/glib/stable/glib-GVariantType.html
- */
-
- /**
- * Converts the given GVariant to a Java object.
- * (Only subset of types is currently supported).
- *
- * We assume that the given gvariant does not contain errors. (checked by webextension first).
- *
- * @param gVariant a pointer to the native GVariant
- */
- static Object convertGVariantToJava(long gVariant){
-
- if (OS.g_variant_is_of_type(gVariant, OS.G_VARIANT_TYPE_BOOLEAN)){
- return OS.g_variant_get_boolean(gVariant);
- }
-
- // see: WebKitGTK.java 'TYPE NOTES'
- if (OS.g_variant_is_of_type(gVariant, OS.G_VARIANT_TYPE_BYTE)) {
- byte byteVal = OS.g_variant_get_byte(gVariant);
-
- switch (byteVal) {
- case WebkitGDBus.SWT_DBUS_MAGIC_NUMBER_NULL:
- return null;
- case WebkitGDBus.SWT_DBUS_MAGIC_NUMBER_EMPTY_ARRAY:
- return new Object [0];
- default:
- System.err.println("SWT WebKitGDBus: received an unsupported byte type via GDBus: " + byteVal);
- break;
- }
- }
-
- if (OS.g_variant_is_of_type(gVariant, OS.G_VARIANT_TYPE_DOUBLE)){
- return OS.g_variant_get_double(gVariant);
- }
-
- if (OS.g_variant_is_of_type(gVariant, OS.G_VARIANT_TYPE_UINT64)){
- return OS.g_variant_get_uint64(gVariant);
- }
-
- if (OS.g_variant_is_of_type(gVariant, OS.G_VARIANT_TYPE_STRING)){
- return Converter.cCharPtrToJavaString(OS.g_variant_get_string(gVariant, null), false);
- }
-
- if (OS.g_variant_is_of_type(gVariant, OS.G_VARIANT_TYPE_TUPLE)){
- int length = (int)OS.g_variant_n_children (gVariant);
- Object[] result = new Object[length];
- for (int i = 0; i < length; i++) {
- result[i] = convertGVariantToJava (OS.g_variant_get_child_value(gVariant, i));
- }
- return result;
- }
-
- String typeString = Converter.cCharPtrToJavaString(OS.g_variant_get_type_string(gVariant), false);
- SWT.error (SWT.ERROR_INVALID_ARGUMENT, new Throwable("Unhandled variant type " + typeString ));
- return null;
- }
-
- /**
- * Converts the given Java Object to a GVariant * representation.
- * (Only subset of types is currently supported).
- *
- * We assume that input Object may contain invalid types.
- *
- * @return pointer GVariant *
- */
- static long convertJavaToGVariant(Object javaObject) throws SWTException {
-
- if (javaObject == null) {
- return OS.g_variant_new_byte(WebkitGDBus.SWT_DBUS_MAGIC_NUMBER_NULL); // see: WebKitGTK.java 'TYPE NOTES'
- }
-
- if (javaObject instanceof Long) {
- return OS.g_variant_new_uint64((Long) javaObject);
- }
-
- if (javaObject instanceof String) {
- return OS.g_variant_new_string (Converter.javaStringToCString((String) javaObject));
- }
-
- if (javaObject instanceof Boolean) {
- return OS.g_variant_new_boolean((Boolean) javaObject);
- }
-
- // We treat Integer, Long, Double, Short as a 'double' because in Javascript these are all 'double'.
- // Note, they all extend 'Number' java type, so they are an instance of it.
- if (javaObject instanceof Number) { // see: WebKitGTK.java 'TYPE NOTES'
- return OS.g_variant_new_double (((Number) javaObject).doubleValue());
- }
-
- if (javaObject instanceof Object[]) {
- Object[] arrayValue = (Object[]) javaObject;
- int length = arrayValue.length;
-
- if (length == 0) {
- return OS.g_variant_new_byte(WebkitGDBus.SWT_DBUS_MAGIC_NUMBER_EMPTY_ARRAY); // see: WebKitGTK.java 'TYPE NOTES'
- }
-
- long variants[] = new long [length];
-
- for (int i = 0; i < length; i++) {
- variants[i] = convertJavaToGVariant(arrayValue[i]);
- }
-
- return OS.g_variant_new_tuple(variants, length);
- }
- System.err.println("SWT WebKitGDBus: invalid object being returned to JavaScript: " + javaObject.toString() + "\n"
- + "Only the following are supported: null, String, Boolean, Number(Long,Integer,Double...), Object[] of basic types");
- throw new SWTException(SWT.ERROR_INVALID_ARGUMENT, "Given object is not valid: " + javaObject.toString());
- }
-}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java
index d02d7f967e..a49a689a05 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java
@@ -87,6 +87,8 @@ public class WebKitGTK extends C {
public static final int WEBKIT_WEBSITE_DATA_COOKIES = 1 << 8;
+ public static final int WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START = 0;
+ public static final int WEBKIT_USER_CONTENT_INJECT_TOP_FRAME = 1;
/** Signals */
@@ -114,9 +116,6 @@ public class WebKitGTK extends C {
public static final byte[] failed = ascii ("failed"); // $NON-NLS-1$
public static final byte[] finished = ascii ("finished"); // $NON-NLS-1$
- // Webkit2 extension
- public static final byte[] initialize_web_extensions = ascii ("initialize-web-extensions");
-
// Status text signals
public static final byte[] mouse_target_changed = ascii ("mouse-target-changed"); // $NON-NLS-1$
@@ -180,9 +179,6 @@ public static final native long JSObjectGetProperty(long ctx, long object, long
public static final native long JSObjectGetPropertyAtIndex(long ctx, long object, int propertyIndex, long [] exception);
/** @method flags=dynamic */
-public static final native long JSObjectMakeArray(long ctx, long argumentCount, long [] arguments, long [] exception);
-
-/** @method flags=dynamic */
public static final native long JSStringCreateWithUTF8CString(byte[] string);
/** @method flags=dynamic */
@@ -203,18 +199,6 @@ public static final native void webkit_javascript_result_unref(long js_result);
public static final native int JSValueGetType(long ctx, long value);
/** @method flags=dynamic */
-public static final native long JSValueMakeBoolean(long ctx, int bool);
-
-/** @method flags=dynamic */
-public static final native long JSValueMakeNumber(long ctx, double number);
-
-/** @method flags=dynamic */
-public static final native long JSValueMakeString(long ctx, long string);
-
-/** @method flags=dynamic */
-public static final native long JSValueMakeUndefined(long ctx);
-
-/** @method flags=dynamic */
public static final native double JSValueToNumber(long ctx, long value, long [] exception);
/** @method flags=dynamic */
@@ -377,9 +361,15 @@ public static final native long webkit_web_context_get_cookie_manager(long conte
public static final native long webkit_web_context_get_website_data_manager(long context);
/** @method flags=dynamic */
+public static final native long webkit_web_context_get_security_manager(long context);
+
+/** @method flags=dynamic */
public static final native void webkit_web_context_set_tls_errors_policy(long context, int policy);
/** @method flags=dynamic */
+public static final native void webkit_web_context_register_uri_scheme(long context, byte[] scheme, long callback, long user_data, long user_data_destroy_func);
+
+/** @method flags=dynamic */
public static final native int webkit_web_view_can_go_back(long web_view);
/** @method flags=dynamic */
@@ -404,6 +394,9 @@ public static final native long webkit_web_view_get_page_id(long web_view);
public static final native long webkit_web_view_get_settings(long web_view);
/** @method flags=dynamic */
+public static final native long webkit_web_view_get_user_content_manager(long web_view);
+
+/** @method flags=dynamic */
public static final native long webkit_web_view_get_title(long web_view);
/** @method flags=dynamic */
@@ -444,14 +437,6 @@ public static final native long webkit_web_view_new();
/** @method flags=dynamic */
public static final native long webkit_web_view_new_with_related_view(long web_view);
-
-/** @method flags=dynamic */ // @param context cast=(WebKitWebContext*) @param directory cast=(const gchar *)
-public static final native void webkit_web_context_set_web_extensions_directory(long context, byte[] directory);
-
-/** @method flags=dynamic */
-public static final native void webkit_web_context_set_web_extensions_initialization_user_data(long /* int */ context, long /* int */ user_data);
-
-
/**
* @method flags=dynamic
* @param js_result cast=(gpointer)
@@ -512,6 +497,36 @@ public static final native long webkit_uri_request_get_uri(long request);
/** @method flags=dynamic */
public static final native long webkit_uri_response_get_mime_type(long responce);
+/**
+ * @method flags=dynamic
+ * @param content_type flags=no_out
+ */
+public static final native void webkit_uri_scheme_request_finish(long request, long stream, long stream_length, byte[] content_type);
+
+/** @method flags=dynamic */
+public static final native long webkit_uri_scheme_request_get_uri (long request);
+
+/** @method flags=dynamic */
+public static final native long webkit_uri_scheme_request_get_web_view(long request);
+
+/** @method flags=dynamic */
+public static final native long webkit_user_content_manager_add_script(long manager, long script);
+
+/** @method flags=dynamic */
+public static final native void webkit_user_content_manager_remove_all_scripts(long manager);
+
+/** @method flags=dynamic */
+public static final native void webkit_security_manager_register_uri_scheme_as_secure(long security_manager, byte[] scheme);
+
+/**
+ * @method flags=dynamic
+ * @param source flags=no_out
+ */
+public static final native long webkit_user_script_new (byte[] source, int injected_frames, int injection_time, long allow_list, long block_list);
+
+/** @method flags=dynamic */
+public static final native void webkit_user_script_unref (long user_script);
+
/* --------------------- start SWT natives --------------------- */
public static final native int GdkRectangle_sizeof();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java
index 2d004432bc..23c3df501b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/TextLayout.java
@@ -248,7 +248,7 @@ void computeRuns() {
if (style.strikeout) {
attrStr.addAttribute(OS.NSStrikethroughStyleAttributeName, NSNumber.numberWithInt(OS.NSUnderlineStyleSingle), range);
Color strikeColor = style.strikeoutColor;
- if (strikeColor != null) {
+ if (strikeColor != null && !strikeColor.isDisposed()) {
NSColor color = NSColor.colorWithDeviceRed(strikeColor.handle[0], strikeColor.handle[1], strikeColor.handle[2], 1);
attrStr.addAttribute(OS.NSStrikethroughColorAttributeName, color, range);
}
@@ -277,7 +277,7 @@ void computeRuns() {
if (underlineStyle != 0) {
attrStr.addAttribute(OS.NSUnderlineStyleAttributeName, NSNumber.numberWithInt(underlineStyle), range);
Color underlineColor = style.underlineColor;
- if (underlineColor != null) {
+ if (underlineColor != null && !underlineColor.isDisposed()) {
NSColor color = NSColor.colorWithDeviceRed(underlineColor.handle[0], underlineColor.handle[1], underlineColor.handle[2], 1);
attrStr.addAttribute(OS.NSUnderlineColorAttributeName, color, range);
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Button.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Button.java
index 02cc5bdf67..370c88d76c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Button.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Button.java
@@ -173,7 +173,8 @@ NSSize cellSizeForBounds (long id, long sel, NSRect cellFrame) {
NSAttributedString attribStr = createString(text, null, foreground, style, true, true, true);
NSRect rect = attribStr.boundingRectWithSize(wrapSize, OS.NSStringDrawingUsesLineFragmentOrigin);
attribStr.release();
- double trimHeight = size.height - titleRect.height;
+ // Avoid trim height to be set to a negative value
+ double trimHeight = Math.max(size.height - titleRect.height, 0);
size.height = rect.height;
if (image != null && ((style & (SWT.CHECK|SWT.RADIO)) !=0)) {
NSSize imageSize = image.handle.size();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
index 7f2b241843..d2ef22338b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
@@ -860,8 +860,9 @@ static private void configureSystemOptions () {
* macOS 11 always enables it regardless of sdk. The option is force
* enabled here in case SWT runs with java/launcher linked with older sdk.
*/
- if (!OS.isBigSurOrLater ())
+ if (!OS.isBigSurOrLater ()) {
configureSystemOption ("NSViewAllowsRootLayerBacking", true);
+ }
/*
* Starting with macOS 11, layer backing is always enabled. That's fine.
@@ -874,8 +875,36 @@ static private void configureSystemOptions () {
* things a lot slower. The workaround is to disable the "automatic" image
* format.
*/
- if (OS.isBigSurOrLater ())
+ if (OS.isBigSurOrLater ()) {
configureSystemOption ("NSViewUsesAutomaticLayerBackingStores", false);
+ }
+
+ /*
+ * Bug 578171: There is new code in macOS 12 that remembers which
+ * Shell was active before menu popup was shown and tries to
+ * re-activate after menu popup is closed. Unfortunately there is a
+ * bug in this code: if window list changes, it activates a wrong
+ * Shell.
+ *
+ * This is a bug on its own, but worse yet, this causes a JVM crash
+ * because activating a new Shell causes menu bar to reset its
+ * internal data, which is unexpected to the macOS's menu tracking
+ * loop.
+ *
+ * Both bugs are bugs of macOS itself. The workaround is to disable
+ * the new macOS 12 behavior.
+ *
+ * The condition should be for (macOS >= 12), but it's not possible
+ * to reliably distinguish 11 from 12, see comment for OS.VERSION.
+ * That's fine: older macOS don't know this setting and will not
+ * check for it anyway.
+ */
+ if (OS.isBigSurOrLater ()) {
+ // The name of the option is misleading. What it really means
+ // is whether '-[NSMenuWindowManagerWindow _setVisible:]' shall
+ // save/restore current key window or not.
+ configureSystemOption ("NSMenuWindowManagerWindowShouldSetVisible", true);
+ }
}
/**
@@ -1028,13 +1057,13 @@ void createMainMenu () {
appleMenu.initWithTitle(emptyStr);
OS.objc_msgSend(application.id, OS.sel_registerName("setAppleMenu:"), appleMenu.id);
- title = NSString.stringWith(SWT.getMessage("About") + " " + appName);
+ title = NSString.stringWith(SWT.getMessage("SWT_About") + " " + appName);
menuItem = appleMenu.addItemWithTitle(title, OS.sel_orderFrontStandardAboutPanel_, emptyStr);
menuItem.setTarget(applicationDelegate);
appleMenu.addItem(NSMenuItem.separatorItem());
- title = NSString.stringWith(SWT.getMessage("Preferences..."));
+ title = NSString.stringWith(SWT.getMessage("SWT_Preferences"));
menuItem = appleMenu.addItemWithTitle(title, 0, NSString.stringWith(","));
/*
@@ -1045,7 +1074,7 @@ void createMainMenu () {
appleMenu.addItem(NSMenuItem.separatorItem());
- title = NSString.stringWith(SWT.getMessage("Services"));
+ title = NSString.stringWith(SWT.getMessage("SWT_Services"));
menuItem = appleMenu.addItemWithTitle(title, 0, emptyStr);
NSMenu servicesMenu = (NSMenu)new NSMenu().alloc();
servicesMenu.initWithTitle(emptyStr);
@@ -1055,22 +1084,22 @@ void createMainMenu () {
appleMenu.addItem(NSMenuItem.separatorItem());
- title = NSString.stringWith(SWT.getMessage("Hide") + " " + appName);
+ title = NSString.stringWith(SWT.getMessage("SWT_Hide") + " " + appName);
menuItem = appleMenu.addItemWithTitle(title, OS.sel_hide_, NSString.stringWith("h"));
menuItem.setTarget(applicationDelegate);
- title = NSString.stringWith(SWT.getMessage("Hide Others"));
+ title = NSString.stringWith(SWT.getMessage("SWT_HideOthers"));
menuItem = appleMenu.addItemWithTitle(title, OS.sel_hideOtherApplications_, NSString.stringWith("h"));
menuItem.setKeyEquivalentModifierMask(OS.NSCommandKeyMask | OS.NSAlternateKeyMask);
menuItem.setTarget(applicationDelegate);
- title = NSString.stringWith(SWT.getMessage("Show All"));
+ title = NSString.stringWith(SWT.getMessage("SWT_ShowAll"));
menuItem = appleMenu.addItemWithTitle(title, OS.sel_unhideAllApplications_, emptyStr);
menuItem.setTarget(applicationDelegate);
appleMenu.addItem(NSMenuItem.separatorItem());
- title = NSString.stringWith(SWT.getMessage("Quit") + " " + appName);
+ title = NSString.stringWith(SWT.getMessage("SWT_Quit") + " " + appName);
menuItem = appleMenu.addItemWithTitle(title, OS.sel_applicationShouldTerminate_, NSString.stringWith("q"));
menuItem.setTarget(applicationDelegate);
@@ -5654,28 +5683,24 @@ void applicationWillFinishLaunching (long id, long sel, long notification) {
/* To find the nib look for each of these paths, in order, until one is found:
* /System/Library/..../Resources/<display name>.lproj/DefaultApp.nib
* /System/Library/..../Resources/<language>.lproj/DefaultApp.nib
- * /System/Library/..../Resources/<user's default language>.lproj/DefaultApp.nib
- * /System/Library/..../Resources/English.lproj/DefaultApp.nib.
- * /System/Library/..../Resources/en.lproj/DefaultApp.nib.
+ * /System/Library/..../Resources/Base.lproj/DefaultApp.nib
+ *
+ * If nib file is not found, use the fallback method createMainMenu() to create menu with localized strings.
*/
NSString path;
NSDictionary dict = NSDictionary.dictionaryWithObject(applicationDelegate, NSString.stringWith("NSOwner"));
- NSBundle bundle = NSBundle.bundleWithIdentifier(NSString.stringWith("com.apple.JavaVM"));
+ NSBundle bundle = NSBundle.bundleWithPath(NSString.stringWith("/System/Library/Frameworks/JavaVM.framework/"));
if (bundle != null) {
path = bundle.pathForResource(NSString.stringWith("DefaultApp"), NSString.stringWith("nib"), null, languageDisplayName);
if (path == null) path = bundle.pathForResource(NSString.stringWith("DefaultApp"), NSString.stringWith("nib"), null, NSString.stringWith(languageISOValue));
- if (path == null) path = bundle.pathForResource(NSString.stringWith("DefaultApp"), NSString.stringWith("nib"));
- if (!loaded) loaded = path != null && NSBundle.loadNibFile(path, dict, 0);
- if (!loaded) {
- path = bundle.pathForResource(NSString.stringWith("DefaultApp"), NSString.stringWith("nib"), null, NSString.stringWith("English"));
- if (path == null) path = bundle.pathForResource(NSString.stringWith("DefaultApp"), NSString.stringWith("nib"), null, NSString.stringWith("en"));
- loaded = path != null && NSBundle.loadNibFile(path, dict, 0);
+ if (path == null && languageISOValue.equals("en")) {
+ path = bundle.pathForResource(NSString.stringWith("DefaultApp"), NSString.stringWith("nib"));
}
+ if (!loaded) loaded = path != null && NSBundle.loadNibFile(path, dict, 0);
}
- if (!loaded) {
- path = NSString.stringWith(System.getProperty("java.home") + "/../Resources/English.lproj/DefaultApp.nib");
- loaded = path != null && NSBundle.loadNibFile(path, dict, 0);
- }
+ /*
+ * Create the main menu ourselves if Default.nib was not loaded or was not found for the specific language
+ */
if (!loaded) {
createMainMenu();
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Table.java
index 965fb9d96e..c49f1354fe 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Table.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Table.java
@@ -3636,39 +3636,66 @@ boolean tableView_writeRowsWithIndexes_toPasteboard(long id, long sel, long arg0
return sendMouseEvent(NSApplication.sharedApplication().currentEvent(), SWT.DragDetect, true);
}
+void handleClickSelected() {
+ /*
+ * When there are multiple selected items and one of them is clicked
+ * without modifiers, macOS supports two cases:
+ * 1) For single click, all other items are deselected
+ * 2) For double-click, selection stays as is, allowing to create
+ * double-click event with multiple items.
+ * In order to distinguish between the two, macOS delays (1) by
+ * [NSEvent doubleClickInterval] in order to see if it's case (2).
+ * This causes SWT.Selection to occur after SWT.MouseUp.
+ *
+ * Bug 289483: For consistent cross-platform behavior, we want
+ * SWT.Selection to occur before SWT.MouseUp. The workaround is to
+ * implement (1) in SWT code and ignore the delayed selection event.
+ */
+
+ int clickedRow = selectedRowIndex;
+ selectedRowIndex = -1;
+
+ if (clickedRow == -1) return;
+ if (dragDetected) return;
+
+ // Deselect all items except the clicked one
+ NSTableView widget = (NSTableView)view;
+ NSIndexSet selectedRows = widget.selectedRowIndexes ();
+ int count = (int)selectedRows.count();
+ long [] indexBuffer = new long [count];
+ selectedRows.getIndexes(indexBuffer, count, 0);
+ for (int i = 0; i < count; i++) {
+ if (indexBuffer[i] == clickedRow) continue;
+ ignoreSelect = true;
+ widget.deselectRow (indexBuffer[i]);
+ ignoreSelect = false;
+ }
+
+ // Bug 456602: It's possible that item is removed between mouse
+ // down (where 'selectedRowIndex' was cached) and mouse up (current
+ // code). In such case, all other items are still deselected, because
+ // 1) without workaround, selection should have happened in mouse down,
+ // where item still existed
+ // 2) clicking empty space deselects all items on macOS
+ // If item is deleted, then pending selection is canceled by macOS, so
+ // there's no need to ignore the next selection event.
+ if (clickedRow >= itemCount) return;
+
+ // Emulate SWT.Selection
+ Event event = new Event ();
+ event.item = _getItem(clickedRow);
+ sendSelectionEvent (SWT.Selection, event, false);
+
+ // Ignore real SWT.Selection that will arrive later
+ ignoreSelect = true;
+}
+
@Override
boolean sendMouseEvent(NSEvent nsEvent, int type, boolean send) {
if (type == SWT.DragDetect) {
dragDetected = true;
} else if (type == SWT.MouseUp) {
- /*
- * This code path handles the case of an unmodified click on an already-selected row.
- * To keep the order of events correct, deselect the other selected items and send the
- * selection event before MouseUp is sent. Ignore the next selection event.
- */
- if (selectedRowIndex != -1) {
- if (dragDetected) {
- selectedRowIndex = -1;
- } else {
- NSTableView widget = (NSTableView)view;
- NSIndexSet selectedRows = widget.selectedRowIndexes ();
- int count = (int)selectedRows.count();
- long [] indexBuffer = new long [count];
- selectedRows.getIndexes(indexBuffer, count, 0);
- for (int i = 0; i < count; i++) {
- if (indexBuffer[i] == selectedRowIndex) continue;
- ignoreSelect = true;
- widget.deselectRow (indexBuffer[i]);
- ignoreSelect = false;
- }
-
- Event event = new Event ();
- event.item = _getItem ((int)selectedRowIndex);
- selectedRowIndex = -1;
- sendSelectionEvent (SWT.Selection, event, false);
- ignoreSelect = true;
- }
- }
+ handleClickSelected();
dragDetected = false;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tree.java
index da9954aa6a..1c2de57fa6 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tree.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Tree.java
@@ -2805,11 +2805,7 @@ boolean sendMouseEvent(NSEvent nsEvent, int type, boolean send) {
if (type == SWT.DragDetect) {
dragDetected = true;
} else if (type == SWT.MouseUp) {
- /*
- * This code path handles the case of an unmodified click on an already-selected row.
- * To keep the order of events correct, deselect the other selected items and send the
- * selection event before MouseUp is sent. Ignore the next selection event.
- */
+ // See code comment in Table.handleClickSelected()
if (selectedRowIndex != -1) {
if (dragDetected) {
selectedRowIndex = -1;
@@ -2828,6 +2824,8 @@ boolean sendMouseEvent(NSEvent nsEvent, int type, boolean send) {
Event event = new Event ();
id itemID = widget.itemAtRow (selectedRowIndex);
+ // (itemID = null) means that item was removed after
+ // 'selectedRowIndex' was cached
if (itemID != null) {
Widget item = display.getWidget (itemID.id);
if (item != null && item instanceof TreeItem) {
@@ -3074,7 +3072,7 @@ public void setHeaderVisible (boolean show) {
/**
* Sets the number of root-level items contained in the receiver.
* <p>
- * The fastest way to insert many items is documented in {@link TreeItem#TreeItem(org.eclipse.swt.widgets.Tree,int,int)}
+ * The fastest way to insert many items is documented in {@link TreeItem#TreeItem(Tree,int,int)}
* and {@link TreeItem#setItemCount}
*
* @param count the number of items
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/TreeItem.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/TreeItem.java
index 1fdf19e060..529082d051 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/TreeItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/TreeItem.java
@@ -67,8 +67,8 @@ public class TreeItem extends Item {
* Constructs <code>TreeItem</code> and <em>inserts</em> it into <code>Tree</code>.
* Item is inserted as last direct child of the tree.
* <p>
- * The fastest way to insert many items is documented in {@link org.eclipse.swt.widgets.TreeItem#TreeItem(Tree,int,int)}
- * and {@link org.eclipse.swt.widgets.TreeItem#setItemCount}
+ * The fastest way to insert many items is documented in {@link TreeItem#TreeItem(Tree,int,int)}
+ * and {@link TreeItem#setItemCount}
*
* @param parent a tree control which will be the parent of the new instance (cannot be null)
* @param style no styles are currently supported, pass SWT.NONE
@@ -126,8 +126,8 @@ public TreeItem (Tree parent, int style, int index) {
* Constructs <code>TreeItem</code> and <em>inserts</em> it into <code>Tree</code>.
* Item is inserted as last direct child of the specified <code>TreeItem</code>.
* <p>
- * The fastest way to insert many items is documented in {@link org.eclipse.swt.widgets.TreeItem#TreeItem(Tree,int,int)}
- * and {@link org.eclipse.swt.widgets.TreeItem#setItemCount}
+ * The fastest way to insert many items is documented in {@link TreeItem#TreeItem(Tree,int,int)}
+ * and {@link TreeItem#setItemCount}
*
* @param parentItem a tree control which will be the parent of the new instance (cannot be null)
* @param style no styles are currently supported, pass SWT.NONE
@@ -152,8 +152,8 @@ public TreeItem (TreeItem parentItem, int style) {
* Constructs <code>TreeItem</code> and <em>inserts</em> it into <code>Tree</code>.
* Item is inserted as <code>index</code> direct child of the specified <code>TreeItem</code>.
* <p>
- * The fastest way to insert many items is documented in {@link org.eclipse.swt.widgets.TreeItem#TreeItem(Tree,int,int)}
- * and {@link org.eclipse.swt.widgets.TreeItem#setItemCount}
+ * The fastest way to insert many items is documented in {@link TreeItem#TreeItem(Tree,int,int)}
+ * and {@link TreeItem#setItemCount}
*
* @param parentItem a tree control which will be the parent of the new instance (cannot be null)
* @param style no styles are currently supported, pass SWT.NONE
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java
index d9f38fd976..d20f9ca7c4 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java
@@ -105,7 +105,7 @@ public abstract class Widget {
static final int DEFAULT_HEIGHT = 64;
Widget () {
- /* Do nothing */
+ notifyCreationTracker();
}
/**
@@ -143,6 +143,7 @@ public Widget (Widget parent, int style) {
this.style = style;
display = parent.display;
reskinWidget ();
+ notifyCreationTracker();
}
long accessibleHandle() {
@@ -1376,6 +1377,7 @@ void release (boolean destroy) {
}
}
}
+ notifyDisposalTracker();
}
void releaseChildren (boolean destroy) {
@@ -2190,4 +2192,16 @@ boolean writeSelectionToPasteboard(long id, long sel, long pasteboard, long type
return false;
}
+void notifyCreationTracker() {
+ if (WidgetSpy.isEnabled) {
+ WidgetSpy.getInstance().widgetCreated(this);
+ }
+}
+
+void notifyDisposalTracker() {
+ if (WidgetSpy.isEnabled) {
+ WidgetSpy.getInstance().widgetDisposed(this);
+ }
+}
+
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak b/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak
index a2a919082b..429f0e5b6b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak
@@ -1,5 +1,5 @@
#*******************************************************************************
-# Copyright (c) 2000, 2021 IBM Corporation and others.
+# Copyright (c) 2000, 2022 IBM Corporation and others.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
@@ -13,7 +13,7 @@
#*******************************************************************************
maj_ver=4
-min_ver=950
-rev=3
-comma_ver=4,950,3,0
+min_ver=952
+rev=6
+comma_ver=4,952,6,0
cef_ver=3071 \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java
index 5dadc75cac..97837153a1 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/SWT.java
@@ -2275,6 +2275,7 @@ public class SWT {
* <p><b>Used By:</b></p>
* <ul>
* <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
+ * <li><code>BoderData</code> in a <code>BoderLayout</code></li>
* </ul>
*/
public static final int TOP = UP;
@@ -2299,6 +2300,7 @@ public class SWT {
* <ul>
* <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
* <li><code>TabFolder</code></li>
+ * <li><code>BoderData</code> in a <code>BoderLayout</code></li>
* </ul>
*/
public static final int BOTTOM = DOWN;
@@ -2329,6 +2331,10 @@ public class SWT {
* This constant can also be used to representing the left keyboard
* location during a key event.
* </p>
+ * <p><b>Used By:</b></p>
+ * <ul>
+ * <li><code>BoderData</code> in a <code>BoderLayout</code></li>
+ * </ul>
*/
public static final int LEFT = LEAD;
@@ -2358,6 +2364,10 @@ public class SWT {
* This constant can also be used to representing the right keyboard
* location during a key event.
* </p>
+ * <p><b>Used By:</b></p>
+ * <ul>
+ * <li><code>BoderData</code> in a <code>BoderLayout</code></li>
+ * </ul>
*/
public static final int RIGHT = TRAIL;
@@ -2369,6 +2379,7 @@ public class SWT {
* <li><code>Label</code></li>
* <li><code>TableColumn</code></li>
* <li><code>FormAttachment</code> in a <code>FormLayout</code></li>
+ * <li><code>BoderData</code> in a <code>BoderLayout</code></li>
* </ul>
*/
public static final int CENTER = 1 << 24;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/SWTMessages.properties b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/SWTMessages.properties
index da86f4f1e8..1c9a2c67aa 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/SWTMessages.properties
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/SWTMessages.properties
@@ -126,3 +126,10 @@ SWT_ValidTo=Valid To
SWT_ValidFromTo=Valid from: {0} to: {1}
SWT_Subject=Subject
SWT_SerialNumber=Serial Number
+SWT_About=About
+SWT_Preferences=Preferences...
+SWT_Services=Services
+SWT_Hide=Hide
+SWT_HideOthers=Hide Others
+SWT_ShowAll=Show All
+SWT_Quit=Quit
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/WidgetSpy.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/WidgetSpy.java
new file mode 100644
index 0000000000..0acb6c3479
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/WidgetSpy.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Simeon Andreev and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.internal;
+
+import java.util.*;
+import java.util.List;
+
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Helper class to allow widget creation and disposal monitoring
+ */
+public class WidgetSpy {
+
+ /**
+ * Flag to prevent {@link Widget} from entering this class during debugging,
+ * if tracking of creation and disposal is not enabled.
+ */
+ public static boolean isEnabled;
+
+ private static final WidgetSpy instance = new WidgetSpy();
+
+ private WidgetTracker widgetTracker;
+
+ private WidgetSpy() {
+ // singleton
+ }
+
+ public static WidgetSpy getInstance() {
+ return instance;
+ }
+
+ /**
+ * Enables tracking of {@link Widget} object creation and disposal.
+ *
+ * WARNING: the tracker will be called from the UI thread. Do not block
+ * it and do not throw any exceptions.
+ *
+ * @param tracker notified when a widget is created or disposed. Use
+ * {@code null} to disable tracking. The tracker will be
+ * notified of widgets created and disposed after setting the tracker.
+ */
+ public void setWidgetTracker(WidgetTracker tracker) {
+ isEnabled = tracker != null;
+ widgetTracker = tracker;
+ }
+
+ public void widgetCreated(Widget widget) {
+ if (widgetTracker != null) {
+ widgetTracker.widgetCreated(widget);
+ }
+ }
+
+ public void widgetDisposed(Widget widget) {
+ if (widgetTracker != null) {
+ widgetTracker.widgetDisposed(widget);
+ }
+ }
+
+ /**
+ * Custom callback to register widget creation / disposal
+ */
+ public static interface WidgetTracker {
+ default void widgetCreated(Widget widget) {}
+
+ default void widgetDisposed(Widget widget) {}
+ }
+
+ /**
+ * Default implementation simply collects all created and not disposed widgets
+ */
+ public static class NonDisposedWidgetTracker implements WidgetTracker {
+
+ private final Map<Widget, Error> nonDisposedWidgets = new LinkedHashMap<>();
+ private final Set<Class<? extends Widget> > trackedTypes = new HashSet<>();
+
+ @Override
+ public void widgetCreated(Widget widget) {
+ boolean isTracked = isTracked(widget);
+ if (isTracked) {
+ Error creationException = new Error("Created widget of type: " + widget.getClass().getSimpleName());
+ nonDisposedWidgets.put(widget, creationException);
+ }
+ }
+
+ @Override
+ public void widgetDisposed(Widget widget) {
+ boolean isTracked = isTracked(widget);
+ if (isTracked) {
+ nonDisposedWidgets.remove(widget);
+ }
+ }
+
+ public Map<Widget, Error> getNonDisposedWidgets() {
+ return Collections.unmodifiableMap(nonDisposedWidgets);
+ }
+
+ public void startTracking() {
+ clearNonDisposedWidgets();
+ WidgetSpy.getInstance().setWidgetTracker(this);
+ }
+
+ private void clearNonDisposedWidgets() {
+ nonDisposedWidgets.clear();
+ }
+
+ public void stopTracking() {
+ WidgetSpy.getInstance().setWidgetTracker(null);
+ }
+
+ public void setTrackingEnabled(boolean enabled) {
+ if (enabled) {
+ startTracking();
+ } else {
+ stopTracking();
+ }
+ }
+
+ public void setTrackedTypes(List<Class<? extends Widget>> types) {
+ trackedTypes.clear();
+ trackedTypes.addAll(types);
+ }
+
+ private boolean isTracked(Widget widget) {
+ boolean isTrackingAllTypes = trackedTypes.isEmpty();
+ if (isTrackingAllTypes) {
+ return true;
+ }
+ if (widget != null) {
+ Class<? extends Widget> widgetType = widget.getClass();
+ if (trackedTypes.contains(widgetType)) {
+ return true;
+ }
+ for (Class<? extends Widget> filteredType : trackedTypes) {
+ if (filteredType.isAssignableFrom(widgetType)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/BorderData.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/BorderData.java
new file mode 100644
index 0000000000..bd4dfcb663
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/BorderData.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Christoph Läubrich and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.layout;
+
+import static org.eclipse.swt.SWT.*;
+
+import java.util.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * Controls the several aspects of a {@link BorderLayout}.
+ *
+ * @since 3.119
+ */
+public final class BorderData {
+
+ private final Map<Control, Point> cachedSize = new IdentityHashMap<>(1);
+
+ public int hHint = SWT.DEFAULT;
+ public int wHint = SWT.DEFAULT;
+ public int region = SWT.CENTER;
+
+ /**
+ * creates a {@link BorderData} with default options
+ */
+ public BorderData() {
+ }
+
+ /**
+ * creates a {@link BorderData} initialized with the given region, valid values
+ * are {@link SWT#TOP}, {@link SWT#CENTER}, {@link SWT#LEFT}, {@link SWT#RIGHT},
+ * {@link SWT#BOTTOM}
+ *
+ * @param region the region valid values are {@link SWT#TOP},
+ * {@link SWT#CENTER}, {@link SWT#LEFT}, {@link SWT#RIGHT},
+ * {@link SWT#BOTTOM}
+ */
+ public BorderData(int region) {
+ this.region = region;
+ }
+
+ /**
+ * creates a {@link BorderData} initialized with the given region and width and
+ * height hints
+ *
+ * @param region the region valid values are {@link SWT#TOP},
+ * {@link SWT#CENTER}, {@link SWT#LEFT}, {@link SWT#RIGHT},
+ * {@link SWT#BOTTOM}
+ * @param widthHint the default hint for the width
+ * @param heightHint he default hint for the height
+ */
+ public BorderData(int region, int widthHint, int heightHint) {
+ this.region = region;
+ this.wHint = widthHint;
+ this.hHint = heightHint;
+ }
+
+ Point getSize(Control control) {
+ return cachedSize.computeIfAbsent(control, c -> c.computeSize(wHint, hHint, true));
+ }
+
+ void flushCache(Control control) {
+ cachedSize.remove(control);
+ }
+
+ @Override
+ public String toString() {
+ return "BorderData [region=" + getRegionString(region) + ", hHint=" + hHint + ", wHint=" + wHint + "]";
+ }
+
+ static String getRegionString(int region) {
+ switch (region) {
+ case SWT.TOP:
+ return "SWT.TOP";
+ case SWT.RIGHT:
+ return "SWT.RIGHT";
+ case SWT.BOTTOM:
+ return "SWT.BOTTOM";
+ case SWT.LEFT:
+ return "SWT.LEFT";
+ case SWT.CENTER:
+ return "SWT.CENTER";
+ default:
+ return "SWT.NONE";
+ }
+ }
+
+ /**
+ *
+ * @return the region of this BorderData or {@link SWT#NONE} if it is out of
+ * range
+ */
+ int getRegion() {
+ switch (region) {
+ case TOP:
+ case BOTTOM:
+ case CENTER:
+ case RIGHT:
+ case LEFT:
+ return region;
+ case SWT.NONE:
+ default:
+ return SWT.NONE;
+ }
+ }
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/BorderLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/BorderLayout.java
new file mode 100644
index 0000000000..4f6b176971
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/layout/BorderLayout.java
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Christoph Läubrich and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.layout;
+
+import static org.eclipse.swt.SWT.*;
+
+import java.util.*;
+import java.util.AbstractMap.*;
+import java.util.List;
+import java.util.Map.*;
+import java.util.function.*;
+import java.util.stream.*;
+import java.util.stream.IntStream.*;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * {@link BorderLayout} places controls in five regions
+ *
+ * <pre>
+ * +--------------------------------+
+ * | NORTH / TOP |
+ * +---+------------------------+---+
+ * | | | |
+ * | W | | E |
+ * | E | | A |
+ * | S | | S |
+ * | T | | T |
+ * | / | | / |
+ * | L | CENTER | R |
+ * | E | | I |
+ * | F | | G |
+ * | T | | H |
+ * | | | T |
+ * | | | |
+ * +---+------------------------+---+
+ * | SOUTH / BOTTOM |
+ * +--------------------------------+
+ * </pre>
+ *
+ * The controls at the NORTH/SOUTH borders get their preferred heights, the
+ * controls at the EAST/WEST get their preferred widths and the center region
+ * grow/shrink according to the remaining space. If more than one control is
+ * placed inside a region the controls are equally distributed across their axis
+ * where the grow (CENTER controlled by the {@link BorderLayout#type} value)
+ *
+ * @since 3.119
+ */
+public class BorderLayout extends Layout {
+
+ private static final ToIntFunction<Point> WIDTH = p -> p.x;
+ private static final ToIntFunction<Point> HEIGHT = p -> p.y;
+
+ /**
+ * type specifies how controls will be positioned within the center region.
+ *
+ * The default value is {@link SWT#HORIZONTAL}.
+ *
+ * Possible values are:
+ * <ul>
+ * <li>{@link SWT#HORIZONTAL}: Position the controls horizontally from left to
+ * right</li>
+ * <li>{@link SWT#VERTICAL}: Position the controls vertically from top to
+ * bottom</li>
+ * </ul>
+ */
+ public int type = SWT.HORIZONTAL;
+ /**
+ * marginWidth specifies the number of points of horizontal margin that will be
+ * placed along the left and right edges of the layout.
+ *
+ * The default value is 0.
+ *
+ */
+ public int marginWidth = 0;
+ /**
+ * marginHeight specifies the number of points of vertical margin that will be
+ * placed along the top and bottom edges of the layout.
+ *
+ * The default value is 0.
+ *
+ */
+ public int marginHeight = 0;
+ /**
+ * spacing specifies the number of points between the edge of one region and its
+ * neighboring regions.
+ *
+ * The default value is 0.
+ *
+ */
+ public int spacing = 0;
+ /**
+ * controlSpacing specifies the number of points between the edge of one control
+ * and its neighboring control inside a region.
+ *
+ * The default value is 0.
+ *
+ */
+ public int controlSpacing = 0;
+ /**
+ * If the width of the {@link SWT#LEFT} and {@link SWT#RIGHT} region exceeds the
+ * available space this factor is used to distribute the size to the controls,
+ * valid values range between [0 ... 1]
+ *
+ * The default value is 0.5 (equal distribution of available space)
+ */
+ public double widthDistributionFactor = 0.5;
+ /**
+ * If the height of the {@link SWT#TOP} and {@link SWT#BOTTOM} region exceeds the
+ * available space this factor is used to distribute the size to the controls,
+ * valid values range between [0 ... 1]
+ *
+ * The default value is 0.5 (equal distribution of available space)
+ *
+ */
+ public double heightDistributionFactor = 0.5;
+
+ @Override
+ protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
+ if (hHint > SWT.DEFAULT && wHint > SWT.DEFAULT) {
+ return new Point(wHint, hHint);
+ }
+ Stream<Entry<Control, BorderData>> children = Arrays.stream(composite.getChildren())//
+ .map(control-> borderDataControl(control, flushCache));
+ Map<Integer, List<Entry<Control, BorderData>>> regionMap = children
+ .collect(Collectors.groupingBy(BorderLayout::region));
+ int width;
+ if (wHint <= SWT.DEFAULT) {
+ Builder widthBuilder = IntStream.builder();
+ int northWidth = getTotal(WIDTH, TOP, regionMap);
+ int southWidth = getTotal(WIDTH, BOTTOM, regionMap);
+ int centerWidth;
+ if (type == SWT.HORIZONTAL) {
+ centerWidth = getTotal(WIDTH, CENTER, regionMap);
+ } else {
+ centerWidth = getMax(WIDTH, CENTER, regionMap);
+ }
+ int westWidth = getMax(WIDTH, LEFT, regionMap);
+ int eastWidth = getMax(WIDTH, RIGHT, regionMap);
+ int middleWidth = westWidth + centerWidth + eastWidth;
+ if (centerWidth > 0) {
+ if (westWidth > 0) {
+ middleWidth += spacing;
+ }
+ if (eastWidth > 0) {
+ middleWidth += spacing;
+ }
+ } else if (westWidth > 0 && eastWidth > 0) {
+ middleWidth += spacing;
+ }
+ widthBuilder.add(middleWidth);
+ widthBuilder.add(northWidth);
+ widthBuilder.add(southWidth);
+ width = widthBuilder.build().max().orElse(0) + 2 * marginWidth;
+ } else {
+ width = wHint;
+ }
+ int height;
+ if (hHint <= SWT.DEFAULT) {
+ Builder heightBuilder = IntStream.builder();
+ int northHeight = getMax(HEIGHT, TOP, regionMap);
+ int southHeight = getMax(HEIGHT, BOTTOM, regionMap);
+ int westHeight = getTotal(HEIGHT, LEFT, regionMap);
+ int eastHeight = getTotal(HEIGHT, RIGHT, regionMap);
+ int centerHeight;
+ if (type == SWT.HORIZONTAL) {
+ centerHeight = getMax(HEIGHT, CENTER, regionMap);
+ } else {
+ centerHeight = getTotal(HEIGHT, CENTER, regionMap);
+ }
+ if (centerHeight > 0) {
+ if (northHeight > 0) {
+ centerHeight += spacing;
+ }
+ if (southHeight > 0) {
+ centerHeight += spacing;
+ }
+ }
+ if (westHeight > 0) {
+ if (northHeight > 0) {
+ westHeight += spacing;
+ }
+ if (southHeight > 0) {
+ westHeight += spacing;
+ }
+ }
+ if (eastHeight > 0) {
+ if (northHeight > 0) {
+ eastHeight += spacing;
+ }
+ if (southHeight > 0) {
+ eastHeight += spacing;
+ }
+ }
+ int sum = northHeight + southHeight;
+ heightBuilder.add(westHeight + sum);
+ heightBuilder.add(centerHeight + sum);
+ heightBuilder.add(eastHeight + sum);
+ height = heightBuilder.build().max().orElse(0) + 2 * marginHeight;
+ } else {
+ height = hHint;
+ }
+ return new Point(width, height);
+ }
+
+ /**
+ * Calculates the total W/H according to the extractor
+ *
+ * @param extractor either {@link #WIDTH} or {@link #HEIGHT}
+ * @param region the region to compute
+ * @param regionMap the map of regions
+ * @return the total W/H including the {@link #controlSpacing}
+ */
+ private int getTotal(ToIntFunction<Point> extractor, int region,
+ Map<Integer, List<Entry<Control, BorderData>>> regionMap) {
+ List<Entry<Control, BorderData>> list = regionMap.getOrDefault(region, Collections.emptyList());
+ if (list.isEmpty()) {
+ return 0;
+ }
+ return list.stream().mapToInt(entry -> extractor.applyAsInt(entry.getValue().getSize(entry.getKey()))).sum()
+ + ((list.size() - 1) * controlSpacing);
+ }
+
+ private static int getMax(ToIntFunction<Point> extractor, int region,
+ Map<Integer, List<Entry<Control, BorderData>>> regionMap) {
+ List<Entry<Control, BorderData>> list = regionMap.getOrDefault(region, Collections.emptyList());
+ return getMax(extractor, list);
+ }
+
+ private static int getMax(ToIntFunction<Point> extractor, List<Entry<Control, BorderData>> list) {
+ return list.stream().mapToInt(entry -> extractor.applyAsInt(entry.getValue().getSize(entry.getKey()))).max()
+ .orElse(0);
+ }
+
+ @Override
+ protected void layout(Composite composite, boolean flushCache) {
+ Rectangle clientArea = composite.getClientArea();
+ int clientX = clientArea.x + marginWidth;
+ int clientY = clientArea.y + marginHeight;
+ int clientWidth = clientArea.width - 2 * marginWidth;
+ int clientHeight = clientArea.height - 2 * marginHeight;
+ Stream<Entry<Control, BorderData>> children = Arrays.stream(composite.getChildren())//
+ .map(control-> borderDataControl(control, flushCache));
+ Map<Integer, List<Entry<Control, BorderData>>> regionMap = children
+ .collect(Collectors.groupingBy(BorderLayout::region));
+ regionMap.getOrDefault(SWT.NONE, Collections.emptyList())
+ .forEach(entry -> entry.getKey().setBounds(clientX, clientY, 0, 0));
+ List<Entry<Control, BorderData>> northList = regionMap.getOrDefault(TOP, Collections.emptyList());
+ List<Entry<Control, BorderData>> southList = regionMap.getOrDefault(BOTTOM, Collections.emptyList());
+ List<Entry<Control, BorderData>> westList = regionMap.getOrDefault(LEFT, Collections.emptyList());
+ List<Entry<Control, BorderData>> eastList = regionMap.getOrDefault(RIGHT, Collections.emptyList());
+ List<Entry<Control, BorderData>> centerList = regionMap.getOrDefault(CENTER, Collections.emptyList());
+ int northControlCount = northList.size();
+ int northControlHeight = getMax(HEIGHT, northList);
+ int southControlCount = southList.size();
+ int southControlHeight = getMax(HEIGHT, southList);
+ if (northControlHeight + southControlHeight > clientHeight) {
+ int distributionSize = (int) (clientHeight * heightDistributionFactor);
+ if (northControlHeight > distributionSize) {
+ northControlHeight = distributionSize;
+ }
+ southControlHeight = clientHeight - northControlHeight;
+ }
+ int centerControlHeight = clientHeight - northControlHeight - southControlHeight;
+ int westControlCount = westList.size();
+ int westControlWidth = getMax(WIDTH, westList);
+ int eastControlCount = eastList.size();
+ int eastControlWidth = getMax(WIDTH, eastList);
+ if (westControlWidth + eastControlWidth > clientWidth) {
+ int distributionSize = (int) (clientWidth * widthDistributionFactor);
+ if (westControlWidth > distributionSize) {
+ westControlWidth = distributionSize;
+ }
+ eastControlWidth = clientWidth - westControlWidth;
+ }
+ int centerControlWidth = clientWidth - westControlWidth - eastControlWidth;
+ int centerControlCount = centerList.size();
+ // Full width and preferred height for NORTH and SOUTH if possible
+ if (northControlCount > 0) {
+ int controlWidth = (clientWidth - (northControlCount - 1) * controlSpacing) / northControlCount;
+ int x = clientX;
+ int y = clientY;
+ for (Entry<Control, BorderData> entry : northList) {
+ entry.getKey().setBounds(x, y, controlWidth, northControlHeight);
+ x += controlWidth + controlSpacing;
+ }
+ }
+ if (southControlCount > 0) {
+ int controlWidth = (clientWidth - (southControlCount - 1) * controlSpacing) / southControlCount;
+ int x = clientX;
+ int y = clientY + centerControlHeight + northControlHeight;
+ for (Entry<Control, BorderData> entry : southList) {
+ entry.getKey().setBounds(x, y, controlWidth, southControlHeight);
+ x += controlWidth + controlSpacing;
+ }
+ }
+ // remaining height for WEST and EAST, preferred width for WEST and EAST if
+ // possible ...
+ if (westControlCount > 0) {
+ int x = clientX;
+ int y = clientY + northControlHeight;
+ int h = clientHeight - northControlHeight - southControlHeight;
+ if (northControlCount > 0) {
+ y += spacing;
+ h -= spacing;
+ }
+ if (southControlCount > 0) {
+ h -= spacing;
+ }
+ int controlHeight = (h - (westControlCount - 1) * controlSpacing) / westControlCount;
+ for (Entry<Control, BorderData> entry : westList) {
+ entry.getKey().setBounds(x, y, westControlWidth, controlHeight);
+ y += controlHeight + controlSpacing;
+ }
+ }
+ if (eastControlCount > 0) {
+ int x = clientX + centerControlWidth + westControlWidth;
+ int y = clientY + northControlHeight;
+ int h = clientHeight - northControlHeight - southControlHeight;
+ if (northControlCount > 0) {
+ y += spacing;
+ h -= spacing;
+ }
+ if (southControlCount > 0) {
+ h -= spacing;
+ }
+ int controlHeight = (h - (eastControlCount - 1) * controlSpacing) / eastControlCount;
+ for (Entry<Control, BorderData> entry : eastList) {
+ entry.getKey().setBounds(x, y, eastControlWidth, controlHeight);
+ y += controlHeight + controlSpacing;
+ }
+ }
+ // remaining height and width for CENTER
+ if (centerControlCount > 0) {
+ int x = clientX + westControlWidth;
+ int y = clientY + northControlHeight;
+ int h = centerControlHeight;
+ int w = centerControlWidth;
+ if (westControlCount > 0) {
+ x += spacing;
+ w -= spacing;
+ }
+ if (eastControlCount > 0) {
+ w -= spacing;
+ }
+ if (northControlCount > 0) {
+ y += spacing;
+ h -= spacing;
+ }
+ if (southControlCount > 0) {
+ h -= spacing;
+ }
+ int controlHeight;
+ int controlWidth;
+ if (type == SWT.HORIZONTAL) {
+ controlHeight = h;
+ controlWidth = (w - (centerControlCount - 1) * controlSpacing) / centerControlCount;
+ } else {
+ controlWidth = w;
+ controlHeight = (h - (centerControlCount - 1) * controlSpacing) / centerControlCount;
+ }
+ for (Entry<Control, BorderData> entry : centerList) {
+ entry.getKey().setBounds(x, y, controlWidth, controlHeight);
+ if (type == SWT.HORIZONTAL) {
+ x += controlWidth + controlSpacing;
+ } else {
+ y += controlHeight + controlSpacing;
+ }
+ }
+ }
+ }
+
+ private static <C extends Control> Entry<C, BorderData> borderDataControl(C control, boolean flushCache) {
+ Object layoutData = control.getLayoutData();
+ if (layoutData instanceof BorderData) {
+ BorderData borderData = (BorderData) layoutData;
+ if (flushCache) {
+ borderData.flushCache(control);
+ }
+ return new SimpleEntry<>(control, borderData);
+ } else {
+ return new SimpleEntry<>(control, null);
+ }
+ }
+
+ private static int region(Entry<Control, BorderData> entry) {
+ BorderData borderData = entry.getValue();
+ if (borderData == null) {
+ //we assume all controls without explicit data to be placed in the center area
+ return SWT.CENTER;
+ }
+ return borderData.getRegion();
+ }
+
+ @Override
+ public String toString() {
+ return "BorderLayout [" //
+ + "type=" + ((type == SWT.HORIZONTAL) ? "SWT.HORIZONTAL" : "SWT.VERTICAL") //
+ + ", marginWidth=" + marginWidth //
+ + ", marginHeight=" + marginHeight //
+ + ", spacing=" + spacing //
+ + ", controlSpacing=" + controlSpacing //
+ + ", widthDistributionFactor=" + widthDistributionFactor//
+ + ", heightDistributionFactor=" + heightDistributionFactor //
+ + "]";
+ }
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/version.txt b/bundles/org.eclipse.swt/Eclipse SWT/common/version.txt
index f423d893b9..ccc5290de9 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/common/version.txt
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/version.txt
@@ -1 +1 @@
-version 4.950 \ No newline at end of file
+version 4.952 \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java
index ec5d50b551..7a0f7aee60 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/ImageLoader.java
@@ -17,11 +17,13 @@ package org.eclipse.swt.graphics;
import java.io.*;
import java.util.*;
+import java.util.List;
import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gtk.*;
import org.eclipse.swt.internal.image.*;
+import org.eclipse.swt.widgets.*;
/**
* Instances of this class are used to load images from,
@@ -176,16 +178,12 @@ boolean isInterlacedPNG(byte [] imageAsByteArray) {
}
ImageData [] getImageDataArrayFromStream(InputStream stream) {
- byte[] buffer = new byte[2048];
long loader = GDK.gdk_pixbuf_loader_new();
- int length;
List<ImageData> imgDataList = new ArrayList<>();
try {
// 1) Load InputStream into byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- while ((length = stream.read(buffer)) > -1) {
- baos.write(buffer, 0, length);
- }
+ stream.transferTo(baos);
baos.flush();
byte[] data_buffer = baos.toByteArray();
if (data_buffer.length == 0) SWT.error(SWT.ERROR_UNSUPPORTED_FORMAT); // empty stream
@@ -193,7 +191,20 @@ ImageData [] getImageDataArrayFromStream(InputStream stream) {
// 2) Copy byte array to C memory, write to GdkPixbufLoader
long buffer_ptr = OS.g_malloc(data_buffer.length);
C.memmove(buffer_ptr, data_buffer, data_buffer.length);
- GDK.gdk_pixbuf_loader_write(loader, buffer_ptr, data_buffer.length, null);
+ long [] error = new long [1];
+ GDK.gdk_pixbuf_loader_write(loader, buffer_ptr, data_buffer.length, error);
+ if(error[0] != 0) {
+ /* Bug 576484
+ * It is safe just to assume if this fails it is most likely an IO error
+ * since unsupported format is checked before, and invalid image right after.
+ * Still, check if it belongs to the G_FILE_ERROR domain and IO error code
+ */
+ if(OS.g_error_matches(error[0], OS.g_file_error_quark(), OS.G_FILE_ERROR_IO)){
+ SWT.error(SWT.ERROR_IO, null, Display.extractFreeGError(error[0]));
+ } else {
+ OS.g_error_free(error[0]);
+ }
+ }
GDK.gdk_pixbuf_loader_close(loader, null);
// 3) Get GdkPixbufAnimation from loader
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/GDBus.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/GDBus.java
index 8bda62b217..78def99d4a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/GDBus.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/internal/GDBus.java
@@ -335,7 +335,7 @@ public class GDBus {
*
* @param gVariant a pointer to the native GVariant
*/
- private static Object[] convertGVariantToJava(long gVariant) {
+ public static Object[] convertGVariantToJava(long gVariant) {
Object retVal = convertGVariantToJavaHelper(gVariant);
if (retVal instanceof Object[]) {
return (Object[]) retVal;
@@ -405,7 +405,7 @@ public class GDBus {
*
* @return pointer GVariant *
*/
- private static long convertJavaToGVariant(Object javaObject) throws SWTException {
+ public static long convertJavaToGVariant(Object javaObject) throws SWTException {
if (javaObject == null) {
return 0;
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java
index 07609de651..10a2f92441 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Button.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2020 IBM Corporation and others.
+ * Copyright (c) 2000, 2022 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -304,7 +304,7 @@ void createHandle (int index) {
switch (style & bits) {
case SWT.ARROW:
- byte arrowType [] = GTK.GTK_NAMED_ICON_GO_UP;
+ byte[] arrowType = GTK.GTK_NAMED_ICON_GO_UP;
if ((style & SWT.UP) != 0) arrowType = GTK.GTK_NAMED_ICON_GO_UP;
if ((style & SWT.DOWN) != 0) arrowType = GTK.GTK_NAMED_ICON_GO_DOWN;
if ((style & SWT.LEFT) != 0) arrowType = GTK.GTK_NAMED_ICON_GO_PREVIOUS;
@@ -844,7 +844,7 @@ void _setAlignment (int alignment) {
style &= ~(SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT);
style |= alignment & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT);
boolean isRTL = (style & SWT.RIGHT_TO_LEFT) != 0;
- byte arrowType [] = GTK.GTK_NAMED_ICON_GO_UP;
+ byte[] arrowType = GTK.GTK_NAMED_ICON_GO_UP;
switch (alignment) {
case SWT.UP: arrowType = GTK.GTK_NAMED_ICON_GO_UP; break;
case SWT.DOWN: arrowType = GTK.GTK_NAMED_ICON_GO_DOWN; break;
@@ -1187,7 +1187,7 @@ void setOrientation (boolean create) {
if (labelHandle != 0) GTK.gtk_widget_set_direction (labelHandle, dir);
if (imageHandle != 0) GTK.gtk_widget_set_direction (imageHandle, dir);
if (arrowHandle != 0) {
- byte arrowType [] = (style & SWT.RIGHT_TO_LEFT) != 0 ? GTK.GTK_NAMED_ICON_GO_NEXT : GTK.GTK_NAMED_ICON_GO_PREVIOUS;
+ byte[] arrowType = (style & SWT.RIGHT_TO_LEFT) != 0 ? GTK.GTK_NAMED_ICON_GO_NEXT : GTK.GTK_NAMED_ICON_GO_PREVIOUS;
switch (style & (SWT.LEFT | SWT.RIGHT)) {
case SWT.LEFT: GTK3.gtk_image_set_from_icon_name (arrowHandle, arrowType, GTK.GTK_ICON_SIZE_MENU); break;
case SWT.RIGHT: GTK3.gtk_image_set_from_icon_name (arrowHandle, arrowType, GTK.GTK_ICON_SIZE_MENU); break;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
index ffdbf489ac..d3bb60ab59 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java
@@ -57,6 +57,8 @@ public abstract class Control extends Widget implements Drawable {
static final boolean DISABLE_EMOJI = Boolean.getBoolean("SWT_GTK_INPUT_HINT_NO_EMOJI");
long fixedHandle;
+ long firstFixedHandle = 0;
+ long keyController;
long redrawWindow, enableWindow, provider;
int drawCount, backgroundAlpha = 255;
long dragGesture, zoomGesture, rotateGesture, panGesture;
@@ -432,7 +434,7 @@ void hookEvents () {
private void hookKeyboardAndFocusSignals(long focusHandle) {
if (GTK.GTK4) {
- long keyController = GTK4.gtk_event_controller_key_new();
+ keyController = GTK4.gtk_event_controller_key_new();
GTK4.gtk_widget_add_controller(focusHandle, keyController);
GTK.gtk_event_controller_set_propagation_phase(keyController, GTK.GTK_PHASE_CAPTURE);
OS.g_signal_connect(keyController, OS.key_pressed, display.keyPressReleaseProc, KEY_PRESSED);
@@ -3926,6 +3928,25 @@ void gtk4_focus_enter_event(long controller, long event) {
}
@Override
+void gtk4_focus_window_event(long handle, long event) {
+ super.gtk4_focus_window_event(handle, event);
+
+ if(firstFixedHandle == 0) {
+ long child = handle;
+ //3rd child of shell will be SWTFixed
+ for(int i = 0; i<3; i++) {
+ child = GTK4.gtk_widget_get_first_child(child);
+ }
+ firstFixedHandle = child != 0 ? child:0;
+ }
+
+ if(firstFixedHandle !=0 && GTK.gtk_widget_has_focus(firstFixedHandle)) {
+ if(event == SWT.FocusIn)sendFocusEvent(SWT.FocusIn);
+ else sendFocusEvent(SWT.FocusOut);
+ }
+}
+
+@Override
long gtk_focus_out_event (long widget, long event) {
// widget could be disposed at this point
if (handle != 0) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
index 4dfc47fb1f..4eaa9e6cff 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java
@@ -132,13 +132,13 @@ public class Display extends Device {
Callback eventCallback;
long eventProc, windowProc2, windowProc3, windowProc4, windowProc5, windowProc6;
long changeValueProc;
- long snapshotDrawProc, keyPressReleaseProc, focusProc, enterMotionProc, leaveProc,
+ long snapshotDrawProc, keyPressReleaseProc, focusProc, windowActiveProc, enterMotionProc, leaveProc,
scrollProc, resizeProc, activateProc, gesturePressReleaseProc;
long notifyProc;
long computeSizeProc;
Callback windowCallback2, windowCallback3, windowCallback4, windowCallback5, windowCallback6;
Callback changeValue;
- Callback snapshotDraw, keyPressReleaseCallback, focusCallback, enterMotionCallback, computeSizeCallback,
+ Callback snapshotDraw, keyPressReleaseCallback, focusCallback, windowActiveCallback, enterMotionCallback, computeSizeCallback,
scrollCallback, leaveCallback, resizeCallback, activateCallback, gesturePressReleaseCallback;
Callback notifyCallback;
EventTable eventTable, filterTable;
@@ -222,19 +222,6 @@ public class Display extends Device {
SessionManagerListener sessionManagerListener;
Runnable [] disposeList;
- /*
- * DBus objects to be freed upong Display release. Only public for use in
- * other areas of SWT (i.e. WebKit). See bug 540060.
- */
- /** @noreference */
- public java.util.List<Long> dBusServers = new ArrayList<>();
- /** @noreference */
- public java.util.List<Long> dBusAuthObservers = new ArrayList<>();
- /** @noreference */
- public java.util.List<Long> dBusGUIDS = new ArrayList<>();
- /** @noreference */
- public java.util.List<Long> dBusConnections = new ArrayList<>();
-
/* Deferred Layout list */
Composite[] layoutDeferred;
int layoutDeferredCount;
@@ -3573,6 +3560,9 @@ void initializeCallbacks () {
focusCallback = new Callback(this, "focusProc", void.class, new Type[] {long.class, long.class}); //$NON-NLS-1$
focusProc = focusCallback.getAddress();
+ windowActiveCallback = new Callback(this, "windowActiveProc", void.class, new Type[] {long.class, long.class}); //$NON-NLS-1$
+ windowActiveProc = windowActiveCallback.getAddress();
+
enterMotionCallback = new Callback(this, "enterMotionProc", void.class, new Type[] {
long.class, double.class, double.class, long.class}); //$NON-NLS-1$
enterMotionProc = enterMotionCallback.getAddress ();
@@ -3850,44 +3840,6 @@ void initializeSessionManager() {
}
/**
- * Some parts of SWT (like WebKit) use GDBus for IPC. Some of these objects
- * cannot be disposed of in their own classes due to design challenges.
- * In these instances we release them along with this Display. This ensures
- * no Browser will be using them at disposal time.
- */
-void releaseDBusServices() {
- releaseSessionManager();
- for (long connection : dBusConnections) {
- if (OS.g_dbus_connection_is_closed(connection)) continue;
- long [] error = new long [1];
- boolean closed = OS.g_dbus_connection_close_sync(connection, 0, error);
- if (error[0] != 0) {
- String msg = extractFreeGError(error[0]);
- System.err.println("SWT Display: error closing connection: " + msg);
- }
- if (closed) {
- // Free this as we added a reference to it
- OS.g_object_unref(connection);
- }
- }
- for (long server : dBusServers) {
- OS.g_dbus_server_stop(server);
- OS.g_object_unref(server);
- }
- for (long authObserver : dBusAuthObservers) {
- OS.g_object_unref(authObserver);
- }
- for (long guid : dBusGUIDS) {
- OS.g_free(guid);
- }
- dBusConnections.clear();
- dBusServers.clear();
- dBusAuthObservers.clear();
- dBusGUIDS.clear();
- dBusServers = dBusAuthObservers = dBusGUIDS = dBusConnections = null;
-}
-
-/**
* Helper method to extract GError messages. Only call if the pointer is valid (i.e. non-zero).
*
* @param errorPtr pointer to the GError
@@ -4670,7 +4622,6 @@ protected void release () {
synchronizer.releaseSynchronizer ();
synchronizer = null;
- releaseDBusServices ();
releaseSessionManager ();
releaseDisplay ();
super.release ();
@@ -4701,6 +4652,10 @@ void releaseDisplay () {
focusCallback = null;
focusProc = 0;
+ windowActiveCallback.dispose();
+ windowActiveCallback = null;
+ windowActiveProc = 0;
+
enterMotionCallback.dispose();
enterMotionCallback = null;
enterMotionProc = 0;
@@ -6130,13 +6085,18 @@ boolean scrollProc(long controller, double dx, double dy, long user_data) {
return false;
}
-void focusProc(long controller, long user_data) {
+void focusProc(long controller, long user_data) {;
long handle = GTK.gtk_event_controller_get_widget(controller);
Widget widget = getWidget(handle);
if (widget != null) widget.focusProc(controller, user_data);
}
+void windowActiveProc(long handle, long user_data) {;
+ Widget widget = getWidget(handle);
+ if (widget != null) widget.windowActiveProc(handle, user_data);
+}
+
boolean keyPressReleaseProc(long controller, int keyval, int keycode, int state, long user_data) {
long handle = GTK.gtk_event_controller_get_widget(controller);
Widget widget = getWidget(handle);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
index 23db4e2023..224734ad0e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java
@@ -947,6 +947,7 @@ void hookEvents () {
}
if (GTK.GTK4) {
OS.g_signal_connect_closure (shellHandle, OS.close_request, display.getClosure (CLOSE_REQUEST), false);
+ OS.g_signal_connect(shellHandle, OS.notify_is_active, display.windowActiveProc, FOCUS_IN);
long keyController = GTK4.gtk_event_controller_key_new();
GTK4.gtk_widget_add_controller(shellHandle, keyController);
GTK.gtk_event_controller_set_propagation_phase(keyController, GTK.GTK_PHASE_TARGET);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
index 1e0ec9eca1..cc67a0eef6 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
@@ -2961,6 +2961,32 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
}
}
}
+
+ GdkRectangle rendererRect = new GdkRectangle ();
+ GdkRectangle columnRect = new GdkRectangle ();
+ int y_offset;
+ {
+ /*
+ * SWT creates multiple renderers (kind of sub-columns) per column.
+ * For example: one for checkbox, one for image, one for text.
+ * 'background_area' argument in this function is area of currently
+ * painted renderer. However, for SWT.EraseItem and SWT.PaintItem,
+ * SWT wants entire column's area along with the event. There's api
+ * 'gtk_tree_view_get_background_area()' but it calculates item's
+ * rect in control, which will have wrong Y if item is rendered
+ * separately (for example, for drag image).
+ * The workaround is to take X range from api and Y range from argument.
+ */
+ OS.memmove (rendererRect, background_area, GdkRectangle.sizeof);
+
+ long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
+ GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, columnRect);
+ GTK.gtk_tree_path_free (path);
+
+ y_offset = columnRect.y - rendererRect.y;
+ columnRect.y -= y_offset;
+ }
+
if (item != null) {
if (GTK.GTK_IS_CELL_RENDERER_TOGGLE (cell) || (columnIndex != 0 || (style & SWT.CHECK) == 0)) {
drawFlags = (int)flags;
@@ -2980,10 +3006,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if ((flags & GTK.GTK_CELL_RENDERER_FOCUSED) != 0) drawState |= SWT.FOCUSED;
}
- GdkRectangle rect = new GdkRectangle ();
- long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
- GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, rect);
- GTK.gtk_tree_path_free (path);
+ Rectangle rect = columnRect.toRectangle ();
if ((drawState & SWT.SELECTED) == 0) {
if ((state & PARENT_BACKGROUND) != 0 || backgroundImage != null) {
Control control = findBackgroundControl ();
@@ -3029,23 +3052,36 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if (cr != 0) {
GdkRectangle r = new GdkRectangle();
GDK.gdk_cairo_get_clip_rectangle(cr, r);
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, r.y, r.width, r.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
// Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
} else {
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
// Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
}
+
+ // SWT.PaintItem/SWT.EraseItem often expect that event.y matches
+ // what 'event.item.getBounds()' returns. The workaround is to
+ // adjust coordinate system temporarily.
Event event = new Event ();
- event.item = item;
- event.index = columnIndex;
- event.gc = gc;
- event.detail = drawState;
- Rectangle eventRect = new Rectangle (rect.x, rect.y, rect.width, rect.height);
- event.setBounds (DPIUtil.autoScaleDown (eventRect));
- sendEvent (SWT.EraseItem, event);
+ try {
+ Rectangle eventRect = new Rectangle (rect.x, rect.y, rect.width, rect.height);
+
+ eventRect.y += y_offset;
+ Cairo.cairo_translate (cr, 0, -y_offset);
+
+ event.item = item;
+ event.index = columnIndex;
+ event.gc = gc;
+ event.detail = drawState;
+ event.setBounds (DPIUtil.autoScaleDown (eventRect));
+ sendEvent (SWT.EraseItem, event);
+ } finally {
+ Cairo.cairo_translate (cr, 0, y_offset);
+ }
+
drawForegroundRGBA = null;
drawState = event.doit ? event.detail : 0;
drawFlags &= ~(GTK.GTK_CELL_RENDERER_FOCUSED | GTK.GTK_CELL_RENDERER_SELECTED);
@@ -3074,9 +3110,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if ((drawState & SWT.BACKGROUND) != 0 && (drawState & SWT.SELECTED) == 0) {
GC gc = getGC(cr);
gc.setBackground (item.getBackground (columnIndex));
- GdkRectangle rect = new GdkRectangle ();
- OS.memmove (rect, background_area, GdkRectangle.sizeof);
- gc.fillRectangle(DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height)));
+ gc.fillRectangle (DPIUtil.autoScaleDown (rendererRect.toRectangle ()));
gc.dispose ();
}
if ((drawState & SWT.FOREGROUND) != 0 || GTK.GTK_IS_CELL_RENDERER_TOGGLE (cell)) {
@@ -3102,10 +3136,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if (GTK.GTK_IS_CELL_RENDERER_TEXT (cell)) {
if (hooks (SWT.PaintItem)) {
if (wasSelected) drawState |= SWT.SELECTED;
- GdkRectangle rect = new GdkRectangle ();
- long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
- GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, rect);
- GTK.gtk_tree_path_free (path);
+ Rectangle rect = columnRect.toRectangle ();
ignoreSize = true;
int [] contentX = new int [1], contentWidth = new int [1];
gtk_cell_renderer_get_preferred_size (cell, handle, contentWidth, null);
@@ -3149,18 +3180,30 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
gc.setFont (item.getFont (columnIndex));
if ((style & SWT.MIRRORED) != 0) rect.x = getClientWidth () - rect.width - rect.x;
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
// Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
+ // SWT.PaintItem/SWT.EraseItem often expect that event.y matches
+ // what 'event.item.getBounds()' returns. The workaround is to
+ // adjust coordinate system temporarily.
Event event = new Event ();
- event.item = item;
- event.index = columnIndex;
- event.gc = gc;
- Rectangle eventRect = new Rectangle (rect.x + contentX [0], rect.y, contentWidth [0], rect.height);
- event.setBounds (DPIUtil.autoScaleDown (eventRect));
- event.detail = drawState;
- sendEvent (SWT.PaintItem, event);
+ try {
+ Rectangle eventRect = new Rectangle (rect.x + contentX [0], rect.y, contentWidth [0], rect.height);
+
+ eventRect.y += y_offset;
+ Cairo.cairo_translate (cr, 0, -y_offset);
+
+ event.item = item;
+ event.index = columnIndex;
+ event.gc = gc;
+ event.detail = drawState;
+ event.setBounds (DPIUtil.autoScaleDown (eventRect));
+ sendEvent (SWT.PaintItem, event);
+ } finally {
+ Cairo.cairo_translate (cr, 0, y_offset);
+ }
+
gc.dispose();
}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java
index 723b591b09..bdf0b5fa2a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java
@@ -59,6 +59,15 @@ public class ToolItem extends Item {
boolean mapHooked;
boolean enabled = true;
+ /**
+ * The image that is currently used by the tool item.
+ * Either the image set by client code via {@link #setImage(Image)}
+ * or {@link #setDisabledImage(Image)}, depending on button state.
+ * Or if the button is disabled but no disabled image is specified,
+ * a grayed out version of the "normal" image.
+ */
+ Image currentImage;
+
/**
* Constructs a new instance of this class given its parent
* (which must be a <code>ToolBar</code>) and a style value
@@ -657,6 +666,7 @@ long gtk_create_menu_proxy (long widget) {
return 1;
}
+ Image image = currentImage;
if (image != null) {
ImageList imageList = parent.imageList;
if (imageList != null) {
@@ -1261,6 +1271,7 @@ private void disposeDefault() {
void _setImage (Image image) {
if ((style & SWT.SEPARATOR) != 0) return;
+ currentImage = image;
if (image != null) {
ImageList imageList = parent.imageList;
if (imageList == null) imageList = parent.imageList = new ImageList ();
@@ -1293,15 +1304,7 @@ void _setImage (Image image) {
* required to reset the proxy menu. Otherwise, the
* old menuItem appears in the overflow menu.
*/
- if ((style & SWT.DROP_DOWN) != 0) {
- if (GTK.GTK4) {
- /* TODO: GTK4 have to implement our own overflow menu */
- } else {
- proxyMenuItem = 0;
- proxyMenuItem = GTK3.gtk_tool_item_retrieve_proxy_menu_item (handle);
- OS.g_signal_connect(proxyMenuItem, OS.activate, ToolBar.menuItemSelectedFunc.getAddress(), handle);
- }
- }
+ recreateMenuProxy();
parent.relayout ();
}
@@ -1411,15 +1414,7 @@ public void setText (String string) {
* required to reset the proxy menu. Otherwise, the
* old menuItem appears in the overflow menu.
*/
- if ((style & SWT.DROP_DOWN) != 0) {
- if (GTK.GTK4) {
- /* TODO: GTK4 have to implement our own overflow menu */
- } else {
- proxyMenuItem = 0;
- proxyMenuItem = GTK3.gtk_tool_item_retrieve_proxy_menu_item (handle);
- OS.g_signal_connect(proxyMenuItem, OS.activate, ToolBar.menuItemSelectedFunc.getAddress(), handle);
- }
- }
+ recreateMenuProxy();
parent.relayout ();
}
@@ -1474,15 +1469,7 @@ public void setToolTipText(String string) {
* Otherwise, the old menuItem appears in the overflow
* menu as a blank item.
*/
- if ((style & SWT.DROP_DOWN) != 0) {
- if (GTK.GTK4) {
- /* TODO: GTK4 have to implement our own overflow menu */
- } else {
- proxyMenuItem = 0;
- proxyMenuItem = GTK3.gtk_tool_item_retrieve_proxy_menu_item (handle);
- OS.g_signal_connect(proxyMenuItem, OS.activate, ToolBar.menuItemSelectedFunc.getAddress(), handle);
- }
- }
+ recreateMenuProxy();
}
/**
@@ -1570,4 +1557,15 @@ long dpiChanged(long object, long arg0) {
return 0;
}
+
+private void recreateMenuProxy() {
+ if ((style & SWT.DROP_DOWN) != 0 || proxyMenuItem != 0) {
+ if (GTK.GTK4) {
+ /* TODO: GTK4 have to implement our own overflow menu */
+ } else {
+ proxyMenuItem = 0;
+ proxyMenuItem = GTK3.gtk_tool_item_retrieve_proxy_menu_item (handle);
+ }
+ }
+}
} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
index 77e6bdfd26..cab5bf8567 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
@@ -3168,6 +3168,32 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
}
}
}
+
+ GdkRectangle rendererRect = new GdkRectangle ();
+ GdkRectangle columnRect = new GdkRectangle ();
+ int y_offset;
+ {
+ /*
+ * SWT creates multiple renderers (kind of sub-columns) per column.
+ * For example: one for checkbox, one for image, one for text.
+ * 'background_area' argument in this function is area of currently
+ * painted renderer. However, for SWT.EraseItem and SWT.PaintItem,
+ * SWT wants entire column's area along with the event. There's api
+ * 'gtk_tree_view_get_background_area()' but it calculates item's
+ * rect in control, which will have wrong Y if item is rendered
+ * separately (for example, for drag image).
+ * The workaround is to take X range from api and Y range from argument.
+ */
+ OS.memmove (rendererRect, background_area, GdkRectangle.sizeof);
+
+ long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
+ GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, columnRect);
+ GTK.gtk_tree_path_free (path);
+
+ y_offset = columnRect.y - rendererRect.y;
+ columnRect.y -= y_offset;
+ }
+
if (item != null) {
if (GTK.GTK_IS_CELL_RENDERER_TOGGLE (cell) || ( columnIndex != 0 || (style & SWT.CHECK) == 0)) {
drawFlags = (int)flags;
@@ -3187,10 +3213,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if ((flags & GTK.GTK_CELL_RENDERER_FOCUSED) != 0) drawState |= SWT.FOCUSED;
}
- GdkRectangle rect = new GdkRectangle ();
- long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
- GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, rect);
- GTK.gtk_tree_path_free (path);
+ Rectangle rect = columnRect.toRectangle ();
// Use the x and width information from the Cairo context. See bug 535124.
if (cr != 0) {
GdkRectangle r2 = new GdkRectangle ();
@@ -3243,21 +3266,34 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if (cr != 0) {
// Use the original rectangle, not the Cairo clipping for the y, width, and height values.
// See bug 535124.
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
} else {
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
// Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
}
+
+ // SWT.PaintItem/SWT.EraseItem often expect that event.y matches
+ // what 'event.item.getBounds()' returns. The workaround is to
+ // adjust coordinate system temporarily.
Event event = new Event ();
- event.item = item;
- event.index = columnIndex;
- event.gc = gc;
- Rectangle eventRect = new Rectangle (rect.x, rect.y, rect.width, rect.height);
- event.setBounds (DPIUtil.autoScaleDown (eventRect));
- event.detail = drawState;
- sendEvent (SWT.EraseItem, event);
+ try {
+ Rectangle eventRect = new Rectangle (rect.x, rect.y, rect.width, rect.height);
+
+ eventRect.y += y_offset;
+ Cairo.cairo_translate (cr, 0, -y_offset);
+
+ event.item = item;
+ event.index = columnIndex;
+ event.gc = gc;
+ event.detail = drawState;
+ event.setBounds (DPIUtil.autoScaleDown (eventRect));
+ sendEvent (SWT.EraseItem, event);
+ } finally {
+ Cairo.cairo_translate (cr, 0, y_offset);
+ }
+
drawForegroundRGBA = null;
drawState = event.doit ? event.detail : 0;
drawFlags &= ~(GTK.GTK_CELL_RENDERER_FOCUSED | GTK.GTK_CELL_RENDERER_SELECTED);
@@ -3275,12 +3311,9 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
}
}
if ((drawState & SWT.BACKGROUND) != 0 && (drawState & SWT.SELECTED) == 0) {
-
GC gc = getGC(cr);
gc.setBackground (item.getBackground (columnIndex));
- GdkRectangle rect = new GdkRectangle ();
- OS.memmove (rect, background_area, GdkRectangle.sizeof);
- gc.fillRectangle(DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height)));
+ gc.fillRectangle (DPIUtil.autoScaleDown (rendererRect.toRectangle ()));
gc.dispose ();
}
if ((drawState & SWT.FOREGROUND) != 0 || GTK.GTK_IS_CELL_RENDERER_TOGGLE (cell)) {
@@ -3306,10 +3339,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if (GTK.GTK_IS_CELL_RENDERER_TEXT (cell)) {
if (hooks (SWT.PaintItem)) {
if (wasSelected) drawState |= SWT.SELECTED;
- GdkRectangle rect = new GdkRectangle ();
- long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
- GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, rect);
- GTK.gtk_tree_path_free (path);
+ Rectangle rect = columnRect.toRectangle ();
ignoreSize = true;
int [] contentX = new int [1], contentWidth = new int [1];
gtk_cell_renderer_get_preferred_size (cell, handle, contentWidth, null);
@@ -3339,7 +3369,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
/* indent */
GdkRectangle rect3 = new GdkRectangle ();
GTK.gtk_widget_realize (handle);
- path = GTK.gtk_tree_model_get_path (modelHandle, iter);
+ long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
GTK.gtk_tree_view_get_cell_area (handle, path, columnHandle, rect3);
GTK.gtk_tree_path_free (path);
contentX[0] += rect3.x;
@@ -3362,18 +3392,30 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
rect.x = getClientWidth () - rect.width - rect.x;
}
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
// Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
+ // SWT.PaintItem/SWT.EraseItem often expect that event.y matches
+ // what 'event.item.getBounds()' returns. The workaround is to
+ // adjust coordinate system temporarily.
Event event = new Event ();
- event.item = item;
- event.index = columnIndex;
- event.gc = gc;
- Rectangle eventRect = new Rectangle (rect.x + contentX [0], rect.y, contentWidth [0], rect.height);
- event.setBounds (DPIUtil.autoScaleDown (eventRect));
- event.detail = drawState;
- sendEvent(SWT.PaintItem, event);
+ try {
+ Rectangle eventRect = new Rectangle (rect.x + contentX [0], rect.y, contentWidth [0], rect.height);
+
+ eventRect.y += y_offset;
+ Cairo.cairo_translate (cr, 0, -y_offset);
+
+ event.item = item;
+ event.index = columnIndex;
+ event.gc = gc;
+ event.detail = drawState;
+ event.setBounds (DPIUtil.autoScaleDown (eventRect));
+ sendEvent (SWT.PaintItem, event);
+ } finally {
+ Cairo.cairo_translate (cr, 0, y_offset);
+ }
+
gc.dispose();
}
}
@@ -3500,7 +3542,7 @@ void setItemCount (long parentIter, int count) {
/**
* Sets the number of root-level items contained in the receiver.
* <p>
- * The fastest way to insert many items is documented in {@link TreeItem#TreeItem(org.eclipse.swt.widgets.Tree,int,int)}
+ * The fastest way to insert many items is documented in {@link TreeItem#TreeItem(Tree,int,int)}
* and {@link TreeItem#setItemCount}
*
* @param count the number of items
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java
index c7545f6658..d4f94ac010 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/TreeItem.java
@@ -51,8 +51,8 @@ public class TreeItem extends Item {
* Constructs <code>TreeItem</code> and <em>inserts</em> it into <code>Tree</code>.
* Item is inserted as last direct child of the tree.
* <p>
- * The fastest way to insert many items is documented in {@link org.eclipse.swt.widgets.TreeItem#TreeItem(Tree,int,int)}
- * and {@link org.eclipse.swt.widgets.TreeItem#setItemCount}
+ * The fastest way to insert many items is documented in {@link TreeItem#TreeItem(Tree,int,int)}
+ * and {@link TreeItem#setItemCount}
*
* @param parent a tree control which will be the parent of the new instance (cannot be null)
* @param style no styles are currently supported, pass SWT.NONE
@@ -110,8 +110,8 @@ public TreeItem (Tree parent, int style, int index) {
* Constructs <code>TreeItem</code> and <em>inserts</em> it into <code>Tree</code>.
* Item is inserted as last direct child of the specified <code>TreeItem</code>.
* <p>
- * The fastest way to insert many items is documented in {@link org.eclipse.swt.widgets.TreeItem#TreeItem(Tree,int,int)}
- * and {@link org.eclipse.swt.widgets.TreeItem#setItemCount}
+ * The fastest way to insert many items is documented in {@link TreeItem#TreeItem(Tree,int,int)}
+ * and {@link TreeItem#setItemCount}
*
* @param parentItem a tree control which will be the parent of the new instance (cannot be null)
* @param style no styles are currently supported, pass SWT.NONE
@@ -136,8 +136,8 @@ public TreeItem (TreeItem parentItem, int style) {
* Constructs <code>TreeItem</code> and <em>inserts</em> it into <code>Tree</code>.
* Item is inserted as <code>index</code> direct child of the specified <code>TreeItem</code>.
* <p>
- * The fastest way to insert many items is documented in {@link org.eclipse.swt.widgets.TreeItem#TreeItem(Tree,int,int)}
- * and {@link org.eclipse.swt.widgets.TreeItem#setItemCount}
+ * The fastest way to insert many items is documented in {@link TreeItem#TreeItem(Tree,int,int)}
+ * and {@link TreeItem#setItemCount}
*
* @param parentItem a tree control which will be the parent of the new instance (cannot be null)
* @param style no styles are currently supported, pass SWT.NONE
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java
index 0c301d5b1e..3aa2083ff4 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java
@@ -255,7 +255,9 @@ public abstract class Widget {
/**
* Prevents uninitialized instances from being created outside the package.
*/
-Widget () {}
+Widget () {
+ notifyCreationTracker();
+}
/**
* Constructs a new instance of this class given its parent
@@ -292,6 +294,7 @@ public Widget (Widget parent, int style) {
this.style = style;
display = parent.display;
reskinWidget ();
+ notifyCreationTracker();
}
void _addListener (int eventType, Listener listener) {
@@ -793,6 +796,14 @@ void gtk4_key_release_event(long controller, int keyval, int keycode, int state,
void gtk4_focus_enter_event(long controller, long event) {}
/**
+ * @param handle the handle of the window that caused the event
+ * @param event the type of event, should be FocusIn or FocusOut
+ */
+void gtk4_focus_window_event(long handle, long event) {
+ gtk_focus_in_event (handle, event);
+}
+
+/**
* @param controller the corresponding controller responsible for capturing the event
* @param event the GdkEvent captured
*/
@@ -1345,6 +1356,7 @@ void release (boolean destroy) {
releaseHandle ();
}
}
+ notifyDisposalTracker();
}
}
@@ -1583,7 +1595,8 @@ char [] sendIMKeyEvent (int type, long event, char [] chars) {
int index = 0, count = 0, state = 0;
long ptr = 0;
if (event == 0) {
- ptr = GTK3.gtk_get_current_event ();
+ long controller = Control.getControl(this.handle).keyController;
+ ptr = GTK.GTK4 ? GTK4.gtk_event_controller_get_current_event(controller):GTK3.gtk_get_current_event ();
if (ptr != 0) {
int eventType = GDK.gdk_event_get_event_type(ptr);
eventType = Control.fixGdkEventTypeValues(eventType);
@@ -1603,9 +1616,13 @@ char [] sendIMKeyEvent (int type, long event, char [] chars) {
break;
}
} else {
- int [] buffer = new int [1];
- GTK3.gtk_get_current_event_state (buffer);
- state = buffer [0];
+ if(GTK.GTK4) {
+ state = GTK4.gtk_event_controller_get_current_event_state(controller);
+ } else {
+ int [] buffer = new int [1];
+ GTK3.gtk_get_current_event_state (buffer);
+ state = buffer [0];
+ }
}
} else {
ptr = event;
@@ -1627,13 +1644,13 @@ char [] sendIMKeyEvent (int type, long event, char [] chars) {
* the key by returning null.
*/
if (isDisposed ()) {
- if (ptr != 0 && ptr != event) gdk_event_free (ptr);
+ if (ptr != 0 && ptr != event && !GTK.GTK4) gdk_event_free (ptr);
return null;
}
if (javaEvent.doit) chars [count++] = chars [index];
index++;
}
- if (ptr != 0 && ptr != event) gdk_event_free (ptr);
+ if (ptr != 0 && ptr != event && !GTK.GTK4) gdk_event_free (ptr);
if (count == 0) return null;
if (index != count) {
char [] result = new char [count];
@@ -2295,6 +2312,12 @@ void focusProc(long controller, long user_data) {
}
}
+void windowActiveProc(long handle, long user_data) {
+ long eventType = GTK.gtk_window_is_active(handle) ? SWT.FocusIn:SWT.FocusOut;
+
+ gtk4_focus_window_event(handle, eventType);
+}
+
boolean keyPressReleaseProc(long controller, int keyval, int keycode, int state, long user_data) {
long event = GTK4.gtk_event_controller_get_current_event(controller);
@@ -2520,4 +2543,17 @@ void gtk_widget_size_allocate (long widget, GtkAllocation allocation, int baseli
GTK3.gtk_widget_size_allocate(widget, allocation);
}
}
+
+void notifyCreationTracker() {
+ if (WidgetSpy.isEnabled) {
+ WidgetSpy.getInstance().widgetCreated(this);
+ }
+}
+
+void notifyDisposalTracker() {
+ if (WidgetSpy.isEnabled) {
+ WidgetSpy.getInstance().widgetDisposed(this);
+ }
+}
+
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
index a89ddf86f9..b79fe461f5 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
@@ -1220,12 +1220,14 @@ void drawBitmap(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight,
data.hNullBitmap = 0;
}
}
- if (srcImage.alpha != -1 || srcImage.alphaData != null) {
- drawBitmapAlpha(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, bm, imgWidth, imgHeight);
+ boolean isDib = bm.bmBits != 0;
+ int depth = bm.bmPlanes * bm.bmBitsPixel;
+ if (isDib && depth == 32) {
+ drawBitmapAlpha(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple);
} else if (srcImage.transparentPixel != -1) {
drawBitmapTransparent(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, bm, imgWidth, imgHeight);
} else {
- drawBitmap(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, bm, imgWidth, imgHeight);
+ drawBitmapColor(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple);
}
if (mustRestore) {
long hOldBitmap = OS.SelectObject(memGC.handle, srcImage.handle);
@@ -1233,35 +1235,15 @@ void drawBitmap(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight,
}
}
-void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, BITMAP bm, int imgWidth, int imgHeight) {
- /* Simple cases */
- if (srcImage.alpha == 0) return;
- if (srcImage.alpha == 255) {
- drawBitmap(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple, bm, imgWidth, imgHeight);
- return;
- }
-
+void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {
boolean alphaBlendSupport = true;
boolean isPrinter = OS.GetDeviceCaps(handle, OS.TECHNOLOGY) == OS.DT_RASPRINTER;
+ int sourceAlpha = -1;
if (isPrinter) {
int caps = OS.GetDeviceCaps(handle, OS.SHADEBLENDCAPS);
if (caps != 0) {
- if (srcImage.alpha != -1) {
- alphaBlendSupport = (caps & OS.SB_CONST_ALPHA) != 0;
- } else {
- alphaBlendSupport = (caps & OS.SB_PIXEL_ALPHA) != 0;
- }
- }
- }
- if (alphaBlendSupport) {
- BLENDFUNCTION blend = new BLENDFUNCTION();
- blend.BlendOp = OS.AC_SRC_OVER;
- long srcHdc = OS.CreateCompatibleDC(handle);
- long oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle);
- if (srcImage.alpha != -1) {
- blend.SourceConstantAlpha = (byte)srcImage.alpha;
- OS.AlphaBlend(handle, destX, destY, destWidth, destHeight, srcHdc, srcX, srcY, srcWidth, srcHeight, blend);
- } else {
+ long srcHdc = OS.CreateCompatibleDC(handle);
+ long oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle);
long memDib = Image.createDIB(srcWidth, srcHeight, 32);
if (memDib == 0) SWT.error(SWT.ERROR_NO_HANDLES);
long memHdc = OS.CreateCompatibleDC(handle);
@@ -1271,34 +1253,41 @@ void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHe
OS.BitBlt(memHdc, 0, 0, srcWidth, srcHeight, srcHdc, srcX, srcY, OS.SRCCOPY);
byte[] srcData = new byte[dibBM.bmWidthBytes * dibBM.bmHeight];
OS.MoveMemory(srcData, dibBM.bmBits, srcData.length);
- final int apinc = imgWidth - srcWidth;
- int ap = srcY * imgWidth + srcX, sp = 0;
- byte[] alphaData = srcImage.alphaData;
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
- int alpha = alphaData[ap++] & 0xff;
- int r = ((srcData[sp + 0] & 0xFF) * alpha) + 128;
- r = (r + (r >> 8)) >> 8;
- int g = ((srcData[sp + 1] & 0xFF) * alpha) + 128;
- g = (g + (g >> 8)) >> 8;
- int b = ((srcData[sp + 2] & 0xFF) * alpha) + 128;
- b = (b + (b >> 8)) >> 8;
- srcData[sp+0] = (byte)r;
- srcData[sp+1] = (byte)g;
- srcData[sp+2] = (byte)b;
- srcData[sp+3] = (byte)alpha;
- sp += 4;
+ int size = srcData.length;
+ sourceAlpha = srcData[3] & 0xFF;
+ for (int sp = 7; sp < size; sp += 4) {
+ int currentAlpha = srcData[sp] & 0xFF;
+ if (sourceAlpha != currentAlpha) {
+ sourceAlpha = -1;
+ break;
}
- ap += apinc;
}
- OS.MoveMemory(dibBM.bmBits, srcData, srcData.length);
- blend.SourceConstantAlpha = (byte)0xff;
- blend.AlphaFormat = OS.AC_SRC_ALPHA;
- OS.AlphaBlend(handle, destX, destY, destWidth, destHeight, memHdc, 0, 0, srcWidth, srcHeight, blend);
OS.SelectObject(memHdc, oldMemBitmap);
OS.DeleteDC(memHdc);
OS.DeleteObject(memDib);
+ OS.SelectObject(srcHdc, oldSrcBitmap);
+ OS.DeleteDC(srcHdc);
+ if (sourceAlpha != -1) {
+ if (sourceAlpha == 0) return;
+ if (sourceAlpha == 255) {
+ drawBitmapColor(srcImage, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, simple);
+ return;
+ }
+ alphaBlendSupport = (caps & OS.SB_CONST_ALPHA) != 0;
+ }
+ else {
+ alphaBlendSupport = (caps & OS.SB_PIXEL_ALPHA) != 0;
+ }
}
+ }
+ if (alphaBlendSupport) {
+ BLENDFUNCTION blend = new BLENDFUNCTION();
+ blend.BlendOp = OS.AC_SRC_OVER;
+ long srcHdc = OS.CreateCompatibleDC(handle);
+ long oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle);
+ blend.SourceConstantAlpha = (byte)sourceAlpha;
+ blend.AlphaFormat = OS.AC_SRC_ALPHA;
+ OS.AlphaBlend(handle, destX, destY, destWidth, destHeight, srcHdc, 0, 0, srcWidth, srcHeight, blend);
OS.SelectObject(srcHdc, oldSrcBitmap);
OS.DeleteDC(srcHdc);
return;
@@ -1348,26 +1337,6 @@ void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHe
byte[] srcData = new byte[sizeInBytes];
OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes);
- /* Merge the alpha channel in place */
- int alpha = srcImage.alpha;
- final boolean hasAlphaChannel = (srcImage.alpha == -1);
- if (hasAlphaChannel) {
- final int apinc = imgWidth - srcWidth;
- final int spinc = dibBM.bmWidthBytes - srcWidth * 4;
- int ap = srcY * imgWidth + srcX, sp = 3;
- byte[] alphaData = srcImage.alphaData;
- for (int y = 0; y < srcHeight; ++y) {
- for (int x = 0; x < srcWidth; ++x) {
- srcData[sp] = alphaData[ap++];
- sp += 4;
- }
- ap += apinc;
- sp += spinc;
- }
- }
-
- /* Scale the foreground pixels with alpha */
- OS.MoveMemory(dibBM.bmBits, srcData, sizeInBytes);
/*
* When drawing to a printer, StretchBlt does not correctly stretch if
* the source and destination HDCs are the same. The workaround is to
@@ -1403,10 +1372,10 @@ void drawBitmapAlpha(Image srcImage, int srcX, int srcY, int srcWidth, int srcHe
int dp = 0;
for (int y = 0; y < destHeight; ++y) {
for (int x = 0; x < destWidth; ++x) {
- if (hasAlphaChannel) alpha = srcData[dp + 3] & 0xff;
- destData[dp] += ((srcData[dp] & 0xff) - (destData[dp] & 0xff)) * alpha / 255;
- destData[dp + 1] += ((srcData[dp + 1] & 0xff) - (destData[dp + 1] & 0xff)) * alpha / 255;
- destData[dp + 2] += ((srcData[dp + 2] & 0xff) - (destData[dp + 2] & 0xff)) * alpha / 255;
+ int alpha = srcData[dp + 3] & 0xFF;
+ destData[dp ] += (srcData[dp ] & 0xFF) - (destData[dp ] & 0xFF) * alpha / 255;
+ destData[dp + 1] += (srcData[dp + 1] & 0xFF) - (destData[dp + 1] & 0xFF) * alpha / 255;
+ destData[dp + 2] += (srcData[dp + 2] & 0xFF) - (destData[dp + 2] & 0xFF) * alpha / 255;
dp += 4;
}
dp += dpinc;
@@ -1642,7 +1611,7 @@ void drawBitmapTransparent(Image srcImage, int srcX, int srcY, int srcWidth, int
OS.DeleteDC(srcHdc);
}
-void drawBitmap(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple, BITMAP bm, int imgWidth, int imgHeight) {
+void drawBitmapColor(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {
long srcHdc = OS.CreateCompatibleDC(handle);
long oldSrcBitmap = OS.SelectObject(srcHdc, srcImage.handle);
int dwRop = OS.GetROP2(handle) == OS.R2_XORPEN ? OS.SRCINVERT : OS.SRCCOPY;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
index c0766ccab7..1b38c70d27 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
@@ -112,16 +112,6 @@ public final class Image extends Resource implements Drawable {
GC memGC;
/**
- * the alpha data for the image
- */
- byte[] alphaData;
-
- /**
- * the global alpha value to be used for every pixel
- */
- int alpha = -1;
-
- /**
* ImageFileNameProvider to provide file names at various Zoom levels
*/
private ImageFileNameProvider imageFileNameProvider;
@@ -283,11 +273,6 @@ public Image(Device device, Image srcImage, int flag) {
device.internal_dispose_GC(hDC, null);
transparentPixel = srcImage.transparentPixel;
- alpha = srcImage.alpha;
- if (srcImage.alphaData != null) {
- alphaData = new byte[srcImage.alphaData.length];
- System.arraycopy(srcImage.alphaData, 0, alphaData, 0, alphaData.length);
- }
break;
case SWT.ICON:
handle = OS.CopyImage(srcImage.handle, OS.IMAGE_ICON, rect.width, rect.height, 0);
@@ -977,9 +962,12 @@ void initNative(String filename) {
long [] createGdipImage() {
switch (type) {
case SWT.BITMAP: {
- if (alpha != -1 || alphaData != null || transparentPixel != -1) {
- BITMAP bm = new BITMAP();
- OS.GetObject(handle, BITMAP.sizeof, bm);
+ BITMAP bm = new BITMAP();
+ OS.GetObject(handle, BITMAP.sizeof, bm);
+ int depth = bm.bmPlanes * bm.bmBitsPixel;
+ boolean isDib = bm.bmBits != 0;
+ boolean hasAlpha = isDib && depth == 32;
+ if (hasAlpha || transparentPixel != -1) {
int imgWidth = bm.bmWidth;
int imgHeight = bm.bmHeight;
long hDC = device.internal_new_GC(null);
@@ -993,8 +981,14 @@ long [] createGdipImage() {
OS.GetObject(memDib, BITMAP.sizeof, dibBM);
int sizeInBytes = dibBM.bmWidthBytes * dibBM.bmHeight;
OS.BitBlt(memHdc, 0, 0, imgWidth, imgHeight, srcHdc, 0, 0, OS.SRCCOPY);
+ long hHeap = OS.GetProcessHeap();
+ long pixels = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, sizeInBytes);
+ if (pixels == 0) SWT.error(SWT.ERROR_NO_HANDLES);
byte red = 0, green = 0, blue = 0;
- if (transparentPixel != -1) {
+ if (hasAlpha) {
+ OS.MoveMemory(pixels, bm.bmBits, sizeInBytes);
+ }
+ else {
if (bm.bmBitsPixel <= 8) {
byte[] color = new byte[4];
OS.GetDIBColorTable(srcHdc, transparentPixel, 1, color);
@@ -1029,30 +1023,8 @@ long [] createGdipImage() {
break;
}
}
- }
- OS.SelectObject(srcHdc, oldSrcBitmap);
- OS.SelectObject(memHdc, oldMemBitmap);
- OS.DeleteObject(srcHdc);
- OS.DeleteObject(memHdc);
- byte[] srcData = new byte[sizeInBytes];
- OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes);
- OS.DeleteObject(memDib);
- device.internal_dispose_GC(hDC, null);
- if (alpha != -1) {
- for (int y = 0, dp = 0; y < imgHeight; ++y) {
- for (int x = 0; x < imgWidth; ++x) {
- srcData[dp + 3] = (byte)alpha;
- dp += 4;
- }
- }
- } else if (alphaData != null) {
- for (int y = 0, dp = 0, ap = 0; y < imgHeight; ++y) {
- for (int x = 0; x < imgWidth; ++x) {
- srcData[dp + 3] = alphaData[ap++];
- dp += 4;
- }
- }
- } else if (transparentPixel != -1) {
+ byte[] srcData = new byte[sizeInBytes];
+ OS.MoveMemory(srcData, dibBM.bmBits, sizeInBytes);
for (int y = 0, dp = 0; y < imgHeight; ++y) {
for (int x = 0; x < imgWidth; ++x) {
if (srcData[dp] == blue && srcData[dp + 1] == green && srcData[dp + 2] == red) {
@@ -1063,12 +1035,15 @@ long [] createGdipImage() {
dp += 4;
}
}
+ OS.MoveMemory(pixels, srcData, sizeInBytes);
}
- long hHeap = OS.GetProcessHeap();
- long pixels = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, srcData.length);
- if (pixels == 0) SWT.error(SWT.ERROR_NO_HANDLES);
- OS.MoveMemory(pixels, srcData, sizeInBytes);
- return new long []{Gdip.Bitmap_new(imgWidth, imgHeight, dibBM.bmWidthBytes, Gdip.PixelFormat32bppARGB, pixels), pixels};
+ OS.SelectObject(srcHdc, oldSrcBitmap);
+ OS.SelectObject(memHdc, oldMemBitmap);
+ OS.DeleteObject(srcHdc);
+ OS.DeleteObject(memHdc);
+ OS.DeleteObject(memDib);
+ int pixelFormat = hasAlpha ? Gdip.PixelFormat32bppPARGB : Gdip.PixelFormat32bppARGB;
+ return new long []{Gdip.Bitmap_new(imgWidth, imgHeight, dibBM.bmWidthBytes, pixelFormat, pixels), pixels};
}
return new long []{Gdip.Bitmap_new(handle, 0), 0};
}
@@ -1633,10 +1608,32 @@ public ImageData getImageDataAtCurrentZoom() {
/* Construct and return the ImageData */
ImageData imageData = new ImageData(width, height, depth, palette, 4, data);
imageData.transparentPixel = this.transparentPixel;
- imageData.alpha = alpha;
- if (alpha == -1 && alphaData != null) {
- imageData.alphaData = new byte[alphaData.length];
- System.arraycopy(alphaData, 0, imageData.alphaData, 0, alphaData.length);
+ if (isDib && depth == 32) {
+ byte straightData[] = new byte[imageSize];
+ byte alphaData[] = new byte[width * height];
+ boolean validAlpha = true;
+ for (int ap = 0, dp = 0; validAlpha && ap < alphaData.length; ap++, dp += 4) {
+ int b = data[dp ] & 0xFF;
+ int g = data[dp + 1] & 0xFF;
+ int r = data[dp + 2] & 0xFF;
+ int a = data[dp + 3] & 0xFF;
+ alphaData[ap] = (byte) a;
+ validAlpha = validAlpha && b <= a && g <= a && r <= a;
+ if (a != 0) {
+ straightData[dp ] = (byte) (((b * 0xFF) + a / 2) / a);
+ straightData[dp + 1] = (byte) (((g * 0xFF) + a / 2) / a);
+ straightData[dp + 2] = (byte) (((r * 0xFF) + a / 2) / a);
+ }
+ }
+ if (validAlpha) {
+ imageData.data = straightData;
+ imageData.alphaData = alphaData;
+ }
+ else {
+ for (int dp = 3; dp < imageSize; dp += 4) {
+ data[dp] = (byte) 0xFF;
+ }
+ }
}
return imageData;
}
@@ -1684,6 +1681,7 @@ void init(int width, int height) {
int planes = OS.GetDeviceCaps(hDC, OS.PLANES);
int depth = bits * planes;
if (depth < 16) depth = 16;
+ if (depth > 24) depth = 24;
handle = createDIB(width, height, depth);
}
if (handle != 0) {
@@ -1729,6 +1727,9 @@ static long [] init(Device device, Image image, ImageData i) {
img.alphaData = i.alphaData;
i = img;
}
+
+ boolean hasAlpha = i.alpha != -1 || i.alphaData != null;
+
/*
* Windows supports 16-bit mask of (0x7C00, 0x3E0, 0x1F),
* 24-bit mask of (0xFF0000, 0xFF00, 0xFF) and 32-bit mask
@@ -1745,51 +1746,56 @@ static long [] init(Device device, Image image, ImageData i) {
int newOrder = ImageData.MSB_FIRST;
PaletteData newPalette = null;
- switch (i.depth) {
- case 8:
- /*
- * Bug 566545. Usually each color mask selects a different part of the pixel
- * value to encode the according color. In this common case it is rather trivial
- * to convert an 8-bit direct color image to the Windows supported 16-bit image.
- * However there is no enforcement for the color masks to be disjunct. For
- * example an 8-bit image where all color masks select the same 8-bit of pixel
- * value (mask = 0xFF and shift = 0 for all colors) results in a very efficient
- * 8-bit gray-scale image without the need of defining a color table.
- *
- * That's why we need to calculate the actual required depth if all colors are
- * stored non-overlapping which might require 24-bit instead of the usual
- * expected 16-bit.
- */
- int minDepth = ImageData.getChannelWidth(redMask, palette.redShift)
- + ImageData.getChannelWidth(greenMask, palette.greenShift)
- + ImageData.getChannelWidth(blueMask, palette.blueShift);
- if (minDepth <= 16) {
- newDepth = 16;
+ if (hasAlpha) {
+ newDepth = 32;
+ newPalette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000);
+ }
+ else {
+ switch (i.depth) {
+ case 8:
+ /*
+ * Bug 566545. Usually each color mask selects a different part of the pixel
+ * value to encode the according color. In this common case it is rather trivial
+ * to convert an 8-bit direct color image to the Windows supported 16-bit image.
+ * However there is no enforcement for the color masks to be disjunct. For
+ * example an 8-bit image where all color masks select the same 8-bit of pixel
+ * value (mask = 0xFF and shift = 0 for all colors) results in a very efficient
+ * 8-bit gray-scale image without the need of defining a color table.
+ *
+ * That's why we need to calculate the actual required depth if all colors are
+ * stored non-overlapping which might require 24-bit instead of the usual
+ * expected 16-bit.
+ */
+ int minDepth = ImageData.getChannelWidth(redMask, palette.redShift)
+ + ImageData.getChannelWidth(greenMask, palette.greenShift)
+ + ImageData.getChannelWidth(blueMask, palette.blueShift);
+ if (minDepth <= 16) {
+ newDepth = 16;
+ newOrder = ImageData.LSB_FIRST;
+ newPalette = new PaletteData(0x7C00, 0x3E0, 0x1F);
+ } else {
+ newDepth = 24;
+ newPalette = new PaletteData(0xFF, 0xFF00, 0xFF0000);
+ }
+ break;
+ case 16:
newOrder = ImageData.LSB_FIRST;
- newPalette = new PaletteData(0x7C00, 0x3E0, 0x1F);
- } else {
+ if (!(redMask == 0x7C00 && greenMask == 0x3E0 && blueMask == 0x1F)) {
+ newPalette = new PaletteData(0x7C00, 0x3E0, 0x1F);
+ }
+ break;
+ case 24:
+ if (!(redMask == 0xFF && greenMask == 0xFF00 && blueMask == 0xFF0000)) {
+ newPalette = new PaletteData(0xFF, 0xFF00, 0xFF0000);
+ }
+ break;
+ case 32:
newDepth = 24;
newPalette = new PaletteData(0xFF, 0xFF00, 0xFF0000);
- }
- break;
- case 16:
- newOrder = ImageData.LSB_FIRST;
- if (!(redMask == 0x7C00 && greenMask == 0x3E0 && blueMask == 0x1F)) {
- newPalette = new PaletteData(0x7C00, 0x3E0, 0x1F);
- }
- break;
- case 24:
- if (!(redMask == 0xFF && greenMask == 0xFF00 && blueMask == 0xFF0000)) {
- newPalette = new PaletteData(0xFF, 0xFF00, 0xFF0000);
- }
- break;
- case 32:
- if (!(redMask == 0xFF00 && greenMask == 0xFF0000 && blueMask == 0xFF000000)) {
- newPalette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000);
- }
- break;
- default:
- SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
+ break;
+ default:
+ SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH);
+ }
}
if (newPalette != null) {
ImageData img = new ImageData(i.width, i.height, newDepth, newPalette);
@@ -1808,6 +1814,73 @@ static long [] init(Device device, Image image, ImageData i) {
i = img;
}
}
+ else if (hasAlpha) {
+ int newDepth = 32;
+ PaletteData newPalette = new PaletteData(0xFF00, 0xFF0000, 0xFF000000);
+ int newOrder = ImageData.MSB_FIRST;
+ RGB[] rgbs = i.palette.getRGBs();
+ int length = rgbs.length;
+ byte[] srcReds = new byte[length];
+ byte[] srcGreens = new byte[length];
+ byte[] srcBlues = new byte[length];
+ for (int j = 0; j < rgbs.length; j++) {
+ RGB rgb = rgbs[j];
+ if (rgb == null) continue;
+ srcReds[j] = (byte)rgb.red;
+ srcGreens[j] = (byte)rgb.green;
+ srcBlues[j] = (byte)rgb.blue;
+ }
+ ImageData img = new ImageData(i.width, i.height, newDepth, newPalette);
+ ImageData.blit(ImageData.BLIT_SRC,
+ i.data, i.depth, i.bytesPerLine, i.getByteOrder(), 0, 0, i.width, i.height, srcReds, srcGreens, srcBlues,
+ ImageData.ALPHA_OPAQUE, null, 0, 0, 0,
+ img.data, img.depth, img.bytesPerLine, newOrder, 0, 0, img.width, img.height, newPalette.redMask, newPalette.greenMask, newPalette.blueMask,
+ false, false);
+
+ if (i.transparentPixel != -1) {
+ img.transparentPixel = newPalette.getPixel(i.palette.getRGB(i.transparentPixel));
+ }
+ img.maskPad = i.maskPad;
+ img.maskData = i.maskData;
+ img.alpha = i.alpha;
+ img.alphaData = i.alphaData;
+ i = img;
+ }
+ if (i.alpha != -1) {
+ int alpha = i.alpha & 0xFF;
+ byte[] data = i.data;
+ for (int dp = 0; dp < i.data.length; dp += 4) {
+ /* pre-multiplied alpha */
+ int r = ((data[dp ] & 0xFF) * alpha) + 128;
+ r = (r + (r >> 8)) >> 8;
+ int g = ((data[dp + 1] & 0xFF) * alpha) + 128;
+ g = (g + (g >> 8)) >> 8;
+ int b = ((data[dp + 2] & 0xFF) * alpha) + 128;
+ b = (b + (b >> 8)) >> 8;
+ data[dp ] = (byte) b;
+ data[dp + 1] = (byte) g;
+ data[dp + 2] = (byte) r;
+ data[dp + 3] = (byte) alpha;
+ }
+ }
+ else if (i.alphaData != null) {
+ byte[] data = i.data;
+ for (int ap = 0, dp = 0; dp < i.data.length; ap++, dp += 4) {
+ /* pre-multiplied alpha */
+ int a = i.alphaData[ap] & 0xFF;
+ int r = ((data[dp ] & 0xFF) * a) + 128;
+ r = (r + (r >> 8)) >> 8;
+ int g = ((data[dp + 1] & 0xFF) * a) + 128;
+ g = (g + (g >> 8)) >> 8;
+ int b = ((data[dp + 2] & 0xFF) * a) + 128;
+ b = (b + (b >> 8)) >> 8;
+ data[dp ] = (byte) r;
+ data[dp + 1] = (byte) g;
+ data[dp + 2] = (byte) b;
+ data[dp + 3] = (byte) a;
+ }
+ }
+
/* Construct bitmap info header by hand */
RGB[] rgbs = i.palette.getRGBs();
BITMAPINFOHEADER bmiHeader = new BITMAPINFOHEADER();
@@ -1894,14 +1967,6 @@ static long [] init(Device device, Image image, ImageData i) {
image.handle = hDib;
image.type = SWT.BITMAP;
image.transparentPixel = i.transparentPixel;
- if (image.transparentPixel == -1) {
- image.alpha = i.alpha;
- if (i.alpha == -1 && i.alphaData != null) {
- int length = i.alphaData.length;
- image.alphaData = new byte[length];
- System.arraycopy(i.alphaData, 0, image.alphaData, 0, length);
- }
- }
}
}
return result;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java
index 4f8ae61709..1c71538df3 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/TextLayout.java
@@ -2871,10 +2871,12 @@ StyleItem[] merge (long items, int itemCount) {
}
}
+ boolean mayNeedSplit = true;
int styleLimit = translateOffset(styles[styleIndex + 1].start);
if (styleLimit <= itemLimit) {
int runLen = styleLimit - start;
if (runLen < MAX_RUN_LENGTH) {
+ mayNeedSplit = false;
styleIndex++;
start = styleLimit;
if (start < itemLimit && 0 < start && start < end) {
@@ -2888,7 +2890,7 @@ StyleItem[] merge (long items, int itemCount) {
}
}
int runLen = itemLimit - start;
- if (runLen > MAX_RUN_LENGTH) {
+ if (mayNeedSplit && runLen > MAX_RUN_LENGTH) {
start += splitLongRun(item);
} else if (itemLimit <= styleLimit) {
itemIndex = nextItemIndex;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java
index ff2a39ff6c..34ccb923d2 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/internal/ImageList.java
@@ -151,10 +151,16 @@ long copyWithAlpha (long hBitmap, int background, byte[] alphaData, int destWidt
/* Merge the alpha channel in place */
if (alphaData != null) {
int spinc = dibBM.bmWidthBytes - srcWidth * 4;
- int ap = 0, sp = 3;
+ int ap = 0, sp = 0;
for (int y = 0; y < srcHeight; ++y) {
for (int x = 0; x < srcWidth; ++x) {
- srcData [sp] = alphaData [ap++];
+ int a = alphaData [ap++] & 0xFF;
+ if (a != 0) {
+ srcData [sp ] = (byte)((((srcData [sp ] & 0xFF) * 0xFF) + a / 2) / a);
+ srcData [sp + 1] = (byte)((((srcData [sp + 1] & 0xFF) * 0xFF) + a / 2) / a);
+ srcData [sp + 2] = (byte)((((srcData [sp + 2] & 0xFF) * 0xFF) + a / 2) / a);
+ }
+ srcData [sp + 3] = (byte)a;
sp += 4;
}
sp += spinc;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java
index 82516a201f..592eaedc40 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Button.java
@@ -1433,6 +1433,71 @@ LRESULT wmNotifyChild (NMHDR hdr, long wParam, long lParam) {
return super.wmNotifyChild (hdr, wParam, lParam);
}
+static int getThemeStateId(int style, boolean pressed, boolean enabled) {
+ int direction = style & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT);
+
+ /*
+ * Feature in Windows. DrawThemeBackground() does not mirror the drawing.
+ * The fix is switch left to right and right to left.
+ */
+ if ((style & SWT.MIRRORED) != 0) {
+ if (direction == SWT.LEFT) {
+ direction = SWT.RIGHT;
+ } else if (direction == SWT.RIGHT) {
+ direction = SWT.LEFT;
+ }
+ }
+
+ /*
+ * On Win11, scrollbars no longer show arrows by default.
+ * Arrows only show up when hot/disabled/pushed.
+ * The workaround is to use hot image in place of default.
+ */
+ boolean hot = false;
+ if (OS.WIN32_BUILD >= OS.WIN32_BUILD_WIN11_21H2) {
+ if (!pressed && enabled) {
+ hot = true;
+ }
+ }
+
+ if (hot) {
+ switch (direction) {
+ case SWT.UP: return OS.ABS_UPHOT;
+ case SWT.DOWN: return OS.ABS_DOWNHOT;
+ case SWT.LEFT: return OS.ABS_LEFTHOT;
+ case SWT.RIGHT: return OS.ABS_RIGHTHOT;
+ }
+ }
+
+ if (pressed) {
+ switch (direction) {
+ case SWT.UP: return OS.ABS_UPPRESSED;
+ case SWT.DOWN: return OS.ABS_DOWNPRESSED;
+ case SWT.LEFT: return OS.ABS_LEFTPRESSED;
+ case SWT.RIGHT: return OS.ABS_RIGHTPRESSED;
+ }
+ }
+
+ if (!enabled) {
+ switch (direction) {
+ case SWT.UP: return OS.ABS_UPDISABLED;
+ case SWT.DOWN: return OS.ABS_DOWNDISABLED;
+ case SWT.LEFT: return OS.ABS_LEFTDISABLED;
+ case SWT.RIGHT: return OS.ABS_RIGHTDISABLED;
+ }
+ }
+
+ switch (direction) {
+ case SWT.UP: return OS.ABS_UPNORMAL;
+ case SWT.DOWN: return OS.ABS_DOWNNORMAL;
+ case SWT.LEFT: return OS.ABS_LEFTNORMAL;
+ case SWT.RIGHT: return OS.ABS_RIGHTNORMAL;
+ }
+
+ // Have some sane value if all else fails
+ return OS.ABS_LEFTNORMAL;
+}
+
@Override
LRESULT wmDrawChild (long wParam, long lParam) {
if ((style & SWT.ARROW) == 0) return super.wmDrawChild (wParam, lParam);
@@ -1441,29 +1506,9 @@ LRESULT wmDrawChild (long wParam, long lParam) {
RECT rect = new RECT ();
OS.SetRect (rect, struct.left, struct.top, struct.right, struct.bottom);
if (OS.IsAppThemed ()) {
- int iStateId = OS.ABS_LEFTNORMAL;
- switch (style & (SWT.UP | SWT.DOWN | SWT.LEFT | SWT.RIGHT)) {
- case SWT.UP: iStateId = OS.ABS_UPNORMAL; break;
- case SWT.DOWN: iStateId = OS.ABS_DOWNNORMAL; break;
- case SWT.LEFT: iStateId = OS.ABS_LEFTNORMAL; break;
- case SWT.RIGHT: iStateId = OS.ABS_RIGHTNORMAL; break;
- }
- /*
- * Feature in Windows. DrawThemeBackground() does not mirror the drawing.
- * The fix is switch left to right and right to left.
- */
- if ((style & SWT.MIRRORED) != 0) {
- if ((style & (SWT.LEFT | SWT.RIGHT)) != 0) {
- iStateId = iStateId == OS.ABS_RIGHTNORMAL ? OS.ABS_LEFTNORMAL : OS.ABS_RIGHTNORMAL;
- }
- }
- /*
- * NOTE: The normal, hot, pressed and disabled state is
- * computed relying on the fact that the increment between
- * the direction states is invariant (always separated by 4).
- */
- if (!getEnabled ()) iStateId += OS.ABS_UPDISABLED - OS.ABS_UPNORMAL;
- if ((struct.itemState & OS.ODS_SELECTED) != 0) iStateId += OS.ABS_UPPRESSED - OS.ABS_UPNORMAL;
+ boolean pressed = ((struct.itemState & OS.ODS_SELECTED) != 0);
+ boolean enabled = getEnabled ();
+ int iStateId = getThemeStateId(style, pressed, enabled);
OS.DrawThemeBackground (display.hScrollBarTheme (), struct.hDC, OS.SBP_ARROWBTN, iStateId, rect, null);
} else {
int uState = OS.DFCS_SCROLLLEFT;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Caret.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Caret.java
index bc0f470331..5b5342b940 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Caret.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Caret.java
@@ -38,6 +38,9 @@ import org.eclipse.swt.internal.win32.*;
* @noextend This class is not intended to be subclassed by clients.
*/
public class Caret extends Widget {
+ /** The Caret last updated on the OS-level */
+ private static Caret currentCaret;
+
Canvas parent;
int x, y, width, height;
boolean moved, resized;
@@ -285,6 +288,7 @@ void killFocus () {
void move () {
moved = false;
+ setCurrentCaret(this);
if (!OS.SetCaretPos (x, y)) return;
resizeIME ();
}
@@ -332,6 +336,9 @@ void releaseParent () {
@Override
void releaseWidget () {
super.releaseWidget ();
+ if (isCurrentCaret()) {
+ setCurrentCaret(null);
+ }
parent = null;
image = null;
font = null;
@@ -390,7 +397,7 @@ public void setBounds (int x, int y, int width, int height) {
void setBoundsInPixels (int x, int y, int width, int height) {
boolean samePosition = this.x == x && this.y == y;
boolean sameExtent = this.width == width && this.height == height;
- if (samePosition && sameExtent) return;
+ if (samePosition && sameExtent && isCurrentCaret()) return;
this.x = x;
this.y = y;
this.width = width;
@@ -530,12 +537,20 @@ public void setLocation (int x, int y) {
}
void setLocationInPixels (int x, int y) {
- if (this.x == x && this.y == y) return;
+ if (this.x == x && this.y == y && isCurrentCaret()) return;
this.x = x; this.y = y;
moved = true;
if (isVisible && hasFocus ()) move ();
}
+private boolean isCurrentCaret() {
+ return Caret.currentCaret == this;
+}
+
+private void setCurrentCaret(Caret caret) {
+ Caret.currentCaret = caret;
+}
+
/**
* Sets the receiver's location to the point specified by
* the argument which is relative to the receiver's
@@ -572,7 +587,7 @@ public void setSize (int width, int height) {
}
void setSizeInPixels (int width, int height) {
- if (this.width == width && this.height == height) return;
+ if (this.width == width && this.height == height && isCurrentCaret()) return;
this.width = width; this.height = height;
resized = true;
if (isVisible && hasFocus ()) resize ();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
index 151be728f1..2e71ec17df 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
@@ -991,39 +991,6 @@ static long create32bitDIB (Image image) {
dp += 4;
}
}
- } else if (alpha != -1) {
- for (int y = 0, dp = 0; y < imgHeight; ++y) {
- for (int x = 0; x < imgWidth; ++x) {
- int r = ((srcData[dp + 0] & 0xFF) * alpha) + 128;
- r = (r + (r >> 8)) >> 8;
- int g = ((srcData[dp + 1] & 0xFF) * alpha) + 128;
- g = (g + (g >> 8)) >> 8;
- int b = ((srcData[dp + 2] & 0xFF) * alpha) + 128;
- b = (b + (b >> 8)) >> 8;
- srcData[dp+0] = (byte)r;
- srcData[dp+1] = (byte)g;
- srcData[dp+2] = (byte)b;
- srcData[dp+3] = (byte)alpha;
- dp += 4;
- }
- }
- } else if (alphaData != null) {
- for (int y = 0, dp = 0, ap = 0; y < imgHeight; ++y) {
- for (int x = 0; x < imgWidth; ++x) {
- int a = alphaData[ap++] & 0xFF;
- int r = ((srcData[dp + 0] & 0xFF) * a) + 128;
- r = (r + (r >> 8)) >> 8;
- int g = ((srcData[dp + 1] & 0xFF) * a) + 128;
- g = (g + (g >> 8)) >> 8;
- int b = ((srcData[dp + 2] & 0xFF) * a) + 128;
- b = (b + (b >> 8)) >> 8;
- srcData[dp+0] = (byte)r;
- srcData[dp+1] = (byte)g;
- srcData[dp+2] = (byte)b;
- srcData[dp+3] = (byte)a;
- dp += 4;
- }
- }
} else if (transparentPixel != -1) {
for (int y = 0, dp = 0; y < imgHeight; ++y) {
for (int x = 0; x < imgWidth; ++x) {
@@ -1035,7 +1002,7 @@ static long create32bitDIB (Image image) {
dp += 4;
}
}
- } else {
+ } else if (alpha == -1 && alphaData == null) {
for (int y = 0, dp = 0; y < imgHeight; ++y) {
for (int x = 0; x < imgWidth; ++x) {
srcData [dp + 3] = (byte)0xFF;
@@ -1117,6 +1084,11 @@ static long create32bitDIB (long hBitmap, int alpha, byte [] alphaData, int tran
if (alpha != -1) {
for (int y = 0, dp = 0; y < imgHeight; ++y) {
for (int x = 0; x < imgWidth; ++x) {
+ if (alpha != 0) {
+ srcData [dp ] = (byte)((((srcData[dp ] & 0xFF) * 0xFF) + alpha / 2) / alpha);
+ srcData [dp + 1] = (byte)((((srcData[dp + 1] & 0xFF) * 0xFF) + alpha / 2) / alpha);
+ srcData [dp + 2] = (byte)((((srcData[dp + 2] & 0xFF) * 0xFF) + alpha / 2) / alpha);
+ }
srcData [dp + 3] = (byte)alpha;
dp += 4;
}
@@ -1124,7 +1096,13 @@ static long create32bitDIB (long hBitmap, int alpha, byte [] alphaData, int tran
} else if (alphaData != null) {
for (int y = 0, dp = 0, ap = 0; y < imgHeight; ++y) {
for (int x = 0; x < imgWidth; ++x) {
- srcData [dp + 3] = alphaData [ap++];
+ int a = alphaData [ap++] & 0xFF;
+ if (a != 0) {
+ srcData [dp ] = (byte)((((srcData[dp ] & 0xFF) * 0xFF) + a / 2) / a);
+ srcData [dp + 1] = (byte)((((srcData[dp + 1] & 0xFF) * 0xFF) + a / 2) / a);
+ srcData [dp + 2] = (byte)((((srcData[dp + 2] & 0xFF) * 0xFF) + a / 2) / a);
+ }
+ srcData [dp + 3] = (byte)a;
dp += 4;
}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TableColumn.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TableColumn.java
index 823a620c74..097ab46efa 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TableColumn.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/TableColumn.java
@@ -324,6 +324,75 @@ int getWidthInPixels () {
}
/**
+ * WINAPI doesn't provide any means to request column's optimal size.
+ * There is only an API to resize to optimal size. The workaround is to
+ * 1) disable redraw
+ * 2) resize to optimal
+ * 3) query new column size
+ * 4) set old column size
+ * 5) enable redraw
+ * This preserves old column size. As a consequence, no painting is
+ * needed after enabling redraw.
+ */
+private int calcAutoWidth(int index, boolean withHeader) {
+ long hwnd = parent.handle;
+
+ // WM_SETREDRAW has a side effect of forcing Control to be visible.
+ // On the other hand, if control is invisible, 'WM_SETREDRAW' is not needed.
+ int style = OS.GetWindowLong (hwnd, OS.GWL_STYLE);
+ boolean isTableVisible = ((style & OS.WS_VISIBLE) != 0);
+ boolean isTableDrawing = parent.getDrawing ();
+ boolean needsDisableRedraw = isTableVisible && isTableDrawing;
+
+ try {
+ if (needsDisableRedraw) {
+ // WM_SETREDRAW is used directly, because 'Control.setRedraw()'
+ // also repaints, which is to be avoided in this function.
+ OS.SendMessage (hwnd, OS.WM_SETREDRAW, 0, 0);
+ }
+
+ int oldWidth = (int)OS.SendMessage (hwnd, OS.LVM_GETCOLUMNWIDTH, index, 0);
+
+ /*
+ * Feature in Windows. When LVSCW_AUTOSIZE_USEHEADER is used
+ * with LVM_SETCOLUMNWIDTH to resize the last column, the last
+ * column is expanded to fill the client area. The fix is to
+ * resize the table to be small, set the column width and then
+ * restore the table to its original size.
+ *
+ * Note: temporarily setting LVS_EX_COLUMNSNAPPOINTS may be a
+ * less intrusive workaround.
+ */
+ RECT rect = null;
+ boolean fixWidth = index == parent.getColumnCount () - 1;
+ if (fixWidth) {
+ rect = new RECT ();
+ OS.GetWindowRect (hwnd, rect);
+ OS.UpdateWindow (hwnd);
+ int flags = OS.SWP_NOACTIVATE | OS.SWP_NOMOVE | OS.SWP_NOREDRAW | OS.SWP_NOZORDER;
+ OS.SetWindowPos (hwnd, 0, 0, 0, 0, rect.bottom - rect.top, flags);
+ }
+
+ int resizeType = withHeader ? OS.LVSCW_AUTOSIZE_USEHEADER : OS.LVSCW_AUTOSIZE;
+ OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, resizeType);
+
+ if (fixWidth) {
+ int flags = OS.SWP_NOACTIVATE | OS.SWP_NOMOVE | OS.SWP_NOZORDER;
+ OS.SetWindowPos (hwnd, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, flags);
+ }
+
+ int newWidth = (int)OS.SendMessage (hwnd, OS.LVM_GETCOLUMNWIDTH, index, 0);
+ OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, oldWidth);
+
+ return newWidth;
+ } finally {
+ if (needsDisableRedraw) {
+ OS.SendMessage (hwnd, OS.WM_SETREDRAW, 1, 0);
+ }
+ }
+}
+
+/**
* Causes the receiver to be resized to its preferred size.
* For a composite, this involves computing the preferred size
* from its layout, if there is one.
@@ -381,10 +450,8 @@ public void pack () {
}
if (newFont != 0) OS.SelectObject (hDC, oldFont);
OS.ReleaseDC (hwnd, hDC);
- OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, columnWidth);
} else {
- OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, OS.LVSCW_AUTOSIZE);
- columnWidth = (int)OS.SendMessage (hwnd, OS.LVM_GETCOLUMNWIDTH, index, 0);
+ columnWidth = calcAutoWidth (index, false);
if (index == 0) {
/*
* Bug in Windows. When LVM_SETCOLUMNWIDTH is used with LVSCW_AUTOSIZE
@@ -412,38 +479,19 @@ public void pack () {
}
if (headerWidth > columnWidth) {
if (!hasHeaderImage) {
- /*
- * Feature in Windows. When LVSCW_AUTOSIZE_USEHEADER is used
- * with LVM_SETCOLUMNWIDTH to resize the last column, the last
- * column is expanded to fill the client area. The fix is to
- * resize the table to be small, set the column width and then
- * restore the table to its original size.
- */
- RECT rect = null;
- boolean fixWidth = index == parent.getColumnCount () - 1;
- if (fixWidth) {
- rect = new RECT ();
- OS.GetWindowRect (hwnd, rect);
- OS.UpdateWindow (hwnd);
- int flags = OS.SWP_NOACTIVATE | OS.SWP_NOMOVE | OS.SWP_NOREDRAW | OS.SWP_NOZORDER;
- OS.SetWindowPos (hwnd, 0, 0, 0, 0, rect.bottom - rect.top, flags);
- }
- OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, OS.LVSCW_AUTOSIZE_USEHEADER);
- if (fixWidth) {
- int flags = OS.SWP_NOACTIVATE | OS.SWP_NOMOVE | OS.SWP_NOZORDER;
- OS.SetWindowPos (hwnd, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, flags);
- }
+ // The code has been there for years and it's no longer clear why
+ // not just use 'headerWidth' here. Maybe because SWT's size
+ // calculation is imperfect and WINAPI will do it better?
+ columnWidth = calcAutoWidth (index, true);
} else {
- OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, headerWidth);
- }
- } else {
- if (index == 0) {
- OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, columnWidth);
+ columnWidth = headerWidth;
}
}
+
+ OS.SendMessage (hwnd, OS.LVM_SETCOLUMNWIDTH, index, columnWidth);
+
parent.ignoreColumnResize = false;
- int newWidth = (int)OS.SendMessage (hwnd, OS.LVM_GETCOLUMNWIDTH, index, 0);
- if (oldWidth != newWidth) {
+ if (oldWidth != columnWidth) {
updateToolTip (index);
sendEvent (SWT.Resize);
if (isDisposed ()) return;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java
index 3cb9a97aaf..488cf58683 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java
@@ -125,6 +125,7 @@ public abstract class Widget {
* Prevents uninitialized instances from being created outside the package.
*/
Widget () {
+ notifyCreationTracker();
}
/**
@@ -162,6 +163,7 @@ public Widget (Widget parent, int style) {
this.style = style;
display = parent.display;
reskinWidget ();
+ notifyCreationTracker();
}
void _addListener (int eventType, Listener listener) {
@@ -829,6 +831,7 @@ void release (boolean destroy) {
releaseHandle ();
}
}
+ notifyDisposalTracker();
}
}
@@ -2487,4 +2490,17 @@ LRESULT wmXButtonUp (long hwnd, long wParam, long lParam) {
}
return result;
}
+
+void notifyCreationTracker() {
+ if (WidgetSpy.isEnabled) {
+ WidgetSpy.getInstance().widgetCreated(this);
+ }
+}
+
+void notifyDisposalTracker() {
+ if (WidgetSpy.isEnabled) {
+ WidgetSpy.getInstance().widgetDisposed(this);
+ }
+}
+
}
diff --git a/bundles/org.eclipse.swt/META-INF/MANIFEST.MF b/bundles/org.eclipse.swt/META-INF/MANIFEST.MF
index 6a625d3e24..e17013ede2 100644
--- a/bundles/org.eclipse.swt/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.swt/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-Name: %pluginName
Bundle-Vendor: %providerName
Bundle-SymbolicName: org.eclipse.swt; singleton:=true
-Bundle-Version: 3.118.100.qualifier
+Bundle-Version: 3.119.100.qualifier
Bundle-ManifestVersion: 2
Bundle-Localization: plugin
DynamicImport-Package: org.eclipse.swt.accessibility2
@@ -15,13 +15,13 @@ Export-Package:
org.eclipse.swt.dnd,
org.eclipse.swt.events,
org.eclipse.swt.graphics,
+ org.eclipse.swt.internal;x-friends:="org.eclipse.ui,org.eclipse.swt.tools.spies",
+ org.eclipse.swt.internal.image;x-internal:=true,
org.eclipse.swt.layout,
org.eclipse.swt.opengl,
org.eclipse.swt.printing,
org.eclipse.swt.program,
- org.eclipse.swt.widgets,
- org.eclipse.swt.internal; x-friends:="org.eclipse.ui",
- org.eclipse.swt.internal.image; x-internal:=true
+ org.eclipse.swt.widgets
Eclipse-ExtensibleAPI: true
Bundle-RequiredExecutionEnvironment: JavaSE-11
Automatic-Module-Name: org.eclipse.swt
diff --git a/bundles/org.eclipse.swt/Readme.Win32.md b/bundles/org.eclipse.swt/Readme.Win32.md
index daa9a946ab..a0764e3d31 100644
--- a/bundles/org.eclipse.swt/Readme.Win32.md
+++ b/bundles/org.eclipse.swt/Readme.Win32.md
@@ -21,7 +21,7 @@ libraries in the binary repository.
* Download & install Java *JDK* (Last tested on JDK9) http://www.oracle.com/technetwork/java/javase/downloads/index.html
* Download and install Eclipse. Either the "Eclipse IDE for Eclipse Committers" or a recent integration build:
- http://download.eclipse.org/eclipse/downloads/
+ https://download.eclipse.org/eclipse/downloads/
* (Optionally) install CDT from marketplace if you want to work on C/Native parts of SWT.
* (if not already installed) installed EGit integration.
* Open the git perspective. Add the following two repositories, which can be found on: (use git protocol)
diff --git a/bundles/org.eclipse.swt/buildFragment.xml b/bundles/org.eclipse.swt/buildFragment.xml
index 549a4c0bef..5a12f3e94e 100644
--- a/bundles/org.eclipse.swt/buildFragment.xml
+++ b/bundles/org.eclipse.swt/buildFragment.xml
@@ -258,9 +258,9 @@
<fileset dir="${build.result.folder}/@dot" includes="**" />
</copy>
<copy todir="${destination.temp.folder}/${full.name}">
- <fileset dir="${fragmentdir}" includes="fragment.properties,about.html,about_files/,swt*.dll,libswt*.so,libswt*.sl,libswt*.a,libswt*.jnilib,libXm.so.2,webkitextensions*/libswt*.so,META-INF/,WebView2Loader.dll" />
+ <fileset dir="${fragmentdir}" includes="fragment.properties,about.html,about_files/,swt*.dll,libswt*.so,libswt*.sl,libswt*.a,libswt*.jnilib,libXm.so.2,META-INF/,WebView2Loader.dll" />
</copy>
- <chmod perm="755" dir="${destination.temp.folder}/${full.name}" includes="swt*.dll,libswt*.so,libswt*.sl,libswt*.a,libswt*.jnilib,libXm.so.2,webkitextensions*/libswt*.so,WebView2Loader.dll" />
+ <chmod perm="755" dir="${destination.temp.folder}/${full.name}" includes="swt*.dll,libswt*.so,libswt*.sl,libswt*.a,libswt*.jnilib,libXm.so.2,WebView2Loader.dll" />
<eclipse.versionReplacer path="${destination.temp.folder}/${full.name}" version="${version.suffix}" />
</target>
@@ -271,7 +271,7 @@
<property name="includetranslationfiles" value="true" />
<property name="swtbasename" value="swt" />
<antcall target="build.jars" />
- <jar jarfile="${build.result.folder}/${swtbasename}.jar" basedir="${fragmentdir}" update="true" includes="swt*.dll,libswt*.so,libswt*.sl,libswt*.a,libswt*.jnilib,libXm.so.2,webkitextensions*/libswt*.so,WebView2Loader.dll" />
+ <jar jarfile="${build.result.folder}/${swtbasename}.jar" basedir="${fragmentdir}" update="true" includes="swt*.dll,libswt*.so,libswt*.sl,libswt*.a,libswt*.jnilib,libXm.so.2,WebView2Loader.dll" />
<move file="${build.result.folder}/${swtbasename}.jar" todir="${temp.folder}/swtdownload" />
<delete dir="${build.result.folder}/@dot" />
<antcall target="build.sources" />
diff --git a/bundles/org.eclipse.swt/buildSWT.xml b/bundles/org.eclipse.swt/buildSWT.xml
index 70d0831f3c..07a871d77b 100644
--- a/bundles/org.eclipse.swt/buildSWT.xml
+++ b/bundles/org.eclipse.swt/buildSWT.xml
@@ -66,15 +66,15 @@
<param name="fragment" value="org.eclipse.swt.cocoa.macosx.x86_64"/>
</antcall>
<antcall target="check_fragment_libraries">
- <param name="library_count" value="8"/>
+ <param name="library_count" value="7"/>
<param name="fragment" value="org.eclipse.swt.gtk.linux.aarch64"/>
</antcall>
<antcall target="check_fragment_libraries">
- <param name="library_count" value="8"/>
+ <param name="library_count" value="7"/>
<param name="fragment" value="org.eclipse.swt.gtk.linux.ppc64le"/>
</antcall>
<antcall target="check_fragment_libraries">
- <param name="library_count" value="8"/>
+ <param name="library_count" value="7"/>
<param name="fragment" value="org.eclipse.swt.gtk.linux.x86_64"/>
</antcall>
<antcall target="check_fragment_libraries">
@@ -86,7 +86,7 @@
<target name="check_fragment_libraries" depends="get_version">
<echo>Checking ${fragment}</echo>
<property name="checkdir" value="~/build/check_libraries"/>
- <property name="library_count" value="34"/>
+ <property name="library_count" value="31"/>
<property name="fragment" value=""/>
<fileset id="match" dir="${repo.bin}/bundles/${fragment}" includes="**/org.eclipse.swt.gtk.linux.aarch64/**, **/org.eclipse.swt.gtk.linux.ppc64le/**, **/org.eclipse.swt.gtk.linux.x86_64/**, **/org.eclipse.swt.win32.win32.x86_64/**, **/org.eclipse.swt.cocoa.macosx.aarch64/**, **/org.eclipse.swt.cocoa.macosx.x86_64/**">
<filename regex="[0-9][0-9][0-9][0-9]"/>
@@ -615,7 +615,6 @@
<!-- Get list of files to commit -->
<fileset id="addid" dir="${repo.bin}">
<include name="bundles/*/*${swt_version}*"/>
- <include name="bundles/*/webkitextensions${swt_version}/*${swt_version}*"/>
<include name="bundles/*/build.sha1"/>
<exclude name="**/.git/**"/>
<exclude name="**/tmpdir/**"/>
@@ -788,12 +787,6 @@
port="${port}"
keyfile="${keyfile}"
trust="true"/>
- <scp file="swtbuild@${build_machine}:${lib_output}/webkitextensions${swt_version}/*"
- todir="${output_dir}/webkitextensions${swt_version}/"
- port="${port}"
- keyfile="${keyfile}"
- trust="true"
- failonerror="false"/>
<sshexec host="${build_machine}"
username="swtbuild"
port="${port}"
@@ -804,10 +797,6 @@
<target name="build_local">
<property name="gtk_version" value="3.0" />
- <exec executable="mkdir">
- <arg value="-p"/>
- <arg value="${output_dir}/webkitextensions${swt_version}/"/>
- </exec>
<exec dir="${build_dir}" executable="sh" failonerror="true">
<arg line="build.sh"/>
<env key="GTK_VERSION" value="${gtk_version}"/>
diff --git a/bundles/org.eclipse.swt/pom.xml b/bundles/org.eclipse.swt/pom.xml
index d708f394f1..51cbee8974 100644
--- a/bundles/org.eclipse.swt/pom.xml
+++ b/bundles/org.eclipse.swt/pom.xml
@@ -16,12 +16,12 @@
<parent>
<artifactId>eclipse.platform.swt</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
<artifactId>org.eclipse.swt</artifactId>
- <version>3.118.100-SNAPSHOT</version>
+ <version>3.119.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<properties>
@@ -29,7 +29,7 @@
forceContextQualifier gets updated during build input process using
ant script <SWT source repo>/bundles/org.eclipse.swt/buildInternal.xml
-->
- <forceContextQualifier>v20220119-1826</forceContextQualifier>
+ <forceContextQualifier>v20220326-2203</forceContextQualifier>
<sonar.sources>Eclipse SWT Accessibility/cocoa,Eclipse SWT Accessibility/common,Eclipse SWT Accessibility/gtk,Eclipse SWT Accessibility/win32,Eclipse SWT AWT/cocoa,Eclipse SWT AWT/common,Eclipse SWT AWT/gtk,Eclipse SWT AWT/win32,Eclipse SWT Browser/cocoa,Eclipse SWT Browser/common,Eclipse SWT Browser/gtk,Eclipse SWT Browser/win32,Eclipse SWT Custom Widgets/common,Eclipse SWT Drag and Drop/cocoa,Eclipse SWT Drag and Drop/common,Eclipse SWT Drag and Drop/gtk,Eclipse SWT Drag and Drop/win32,Eclipse SWT OLE Win32/win32,Eclipse SWT OpenGL/cocoa,Eclipse SWT OpenGL/common,Eclipse SWT OpenGL/glx,Eclipse SWT OpenGL/gtk,Eclipse SWT OpenGL/win32,Eclipse SWT PI/cairo,Eclipse SWT PI/cocoa,Eclipse SWT PI/common,Eclipse SWT PI/gtk,Eclipse SWT PI/win32,Eclipse SWT Printing/cocoa,Eclipse SWT Printing/common,Eclipse SWT Printing/gtk,Eclipse SWT Printing/win32,Eclipse SWT Program/cocoa,Eclipse SWT Program/common,Eclipse SWT Program/gtk,Eclipse SWT Program/win32,Eclipse SWT WebKit/cocoa,Eclipse SWT WebKit/gtk,Eclipse SWT/cairo,Eclipse SWT/cocoa,Eclipse SWT/common,Eclipse SWT/emulated/bidi,Eclipse SWT/emulated/coolbar,Eclipse SWT/emulated/expand,Eclipse SWT/emulated/taskbar,Eclipse SWT/emulated/tooltip,Eclipse SWT/gtk,Eclipse SWT/win32</sonar.sources>
</properties>
diff --git a/container/Dockerfile b/container/Dockerfile
index fa7be5dbd8..cd1a4f5649 100644
--- a/container/Dockerfile
+++ b/container/Dockerfile
@@ -1,4 +1,4 @@
-FROM eclipsecbi/fedora-gtk3-mutter:29-gtk3.24
+FROM eclipsecbi/fedora-gtk3-mutter:30-gtk3.24
# Back to root for install
USER 0
diff --git a/examples/org.eclipse.swt.examples.browser.demos/pom.xml b/examples/org.eclipse.swt.examples.browser.demos/pom.xml
index 1bd4f24028..739538de2a 100644
--- a/examples/org.eclipse.swt.examples.browser.demos/pom.xml
+++ b/examples/org.eclipse.swt.examples.browser.demos/pom.xml
@@ -14,7 +14,7 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
diff --git a/examples/org.eclipse.swt.examples.launcher/pom.xml b/examples/org.eclipse.swt.examples.launcher/pom.xml
index 32477aa6f1..f066a82431 100644
--- a/examples/org.eclipse.swt.examples.launcher/pom.xml
+++ b/examples/org.eclipse.swt.examples.launcher/pom.xml
@@ -14,7 +14,7 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
diff --git a/examples/org.eclipse.swt.examples.ole.win32/pom.xml b/examples/org.eclipse.swt.examples.ole.win32/pom.xml
index 6b424468ee..5e50471043 100644
--- a/examples/org.eclipse.swt.examples.ole.win32/pom.xml
+++ b/examples/org.eclipse.swt.examples.ole.win32/pom.xml
@@ -14,7 +14,7 @@
<parent>
<artifactId>eclipse.platform.swt</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
diff --git a/examples/org.eclipse.swt.examples.views/pom.xml b/examples/org.eclipse.swt.examples.views/pom.xml
index 04d7fb8d74..b0af44b7b2 100644
--- a/examples/org.eclipse.swt.examples.views/pom.xml
+++ b/examples/org.eclipse.swt.examples.views/pom.xml
@@ -14,7 +14,7 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
diff --git a/examples/org.eclipse.swt.examples/META-INF/MANIFEST.MF b/examples/org.eclipse.swt.examples/META-INF/MANIFEST.MF
index 9bbf5adabe..a278ed410e 100644
--- a/examples/org.eclipse.swt.examples/META-INF/MANIFEST.MF
+++ b/examples/org.eclipse.swt.examples/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %plugin.SWTStandaloneExampleSet.name
Bundle-SymbolicName: org.eclipse.swt.examples; singleton:=true
-Bundle-Version: 3.107.100.qualifier
+Bundle-Version: 3.107.200.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-11
diff --git a/examples/org.eclipse.swt.examples/pom.xml b/examples/org.eclipse.swt.examples/pom.xml
index 89677ad88b..82f064df74 100644
--- a/examples/org.eclipse.swt.examples/pom.xml
+++ b/examples/org.eclipse.swt.examples/pom.xml
@@ -14,11 +14,11 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
<artifactId>org.eclipse.swt.examples</artifactId>
- <version>3.107.100-SNAPSHOT</version>
+ <version>3.107.200-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/controlexample/browser-content.html b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/controlexample/browser-content.html
index bcb8288efc..3fb059c6b3 100644
--- a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/controlexample/browser-content.html
+++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/controlexample/browser-content.html
@@ -22,7 +22,7 @@ and more, check out <a href="http://www.eclipse.org/swt/">http://www.eclipse.org
<h3>Eclipse Downloads Page</h3>
<p>To download the latest Integration Build of eclipse, go to:
-<a href="http://download.eclipse.org/eclipse/downloads/">http://download.eclipse.org/eclipse/downloads</a>.</p>
+<a href="https://download.eclipse.org/eclipse/downloads/">https://download.eclipse.org/eclipse/downloads</a>.</p>
<h3>Bug Reports and Feature Requests</h3>
<p>To report an SWT bug or request an SWT feature, go to:
diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/imageanalyzer/ImageAnalyzer.java b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/imageanalyzer/ImageAnalyzer.java
index 1638aa6d44..326e3d0668 100644
--- a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/imageanalyzer/ImageAnalyzer.java
+++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/imageanalyzer/ImageAnalyzer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2017 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -205,7 +205,7 @@ public class ImageAnalyzer {
shell.setText(bundle.getString("Image_analyzer"));
// Hook resize and dispose listeners.
- shell.addControlListener(ControlListener.controlResizedAdapter(e-> resizeShell(e)));
+ shell.addControlListener(ControlListener.controlResizedAdapter(this::resizeShell));
shell.addShellListener(ShellListener.shellClosedAdapter(e -> {
animate = false; // stop any animation in progress
if (animateThread != null) {
@@ -833,7 +833,7 @@ public class ImageAnalyzer {
loader = new ImageLoader();
if (incremental) {
// Prepare to handle incremental events.
- loader.addImageLoaderListener(event -> incrementalDataLoaded(event));
+ loader.addImageLoaderListener(this::incrementalDataLoaded);
incrementalThreadStart();
}
// Read the new image(s) from the chosen file.
@@ -884,7 +884,7 @@ public class ImageAnalyzer {
loader = new ImageLoader();
if (incremental) {
// Prepare to handle incremental events.
- loader.addImageLoaderListener(event -> incrementalDataLoaded(event));
+ loader.addImageLoaderListener(this::incrementalDataLoaded);
incrementalThreadStart();
}
// Read the new image(s) from the chosen URL.
@@ -929,7 +929,7 @@ public class ImageAnalyzer {
// Synchronize so we don't try to remove when the vector is null.
synchronized (ImageAnalyzer.this) {
if (incrementalEvents != null) {
- if (incrementalEvents.size() > 0) {
+ if (!incrementalEvents.isEmpty()) {
ImageLoaderEvent event = incrementalEvents.remove(0);
if (image != null) image.dispose();
image = new Image(display, event.imageData);
@@ -1655,22 +1655,19 @@ public class ImageAnalyzer {
shell.setText(string);
if (imageDataArray.length > 1) {
- string = createMsg(bundle.getString("Type_index"),
- new Object[] {fileTypeString(imageData.type),
- Integer.valueOf(imageDataIndex + 1),
- Integer.valueOf(imageDataArray.length)});
+ string = createMsg(bundle.getString("Type_index"), fileTypeString(imageData.type),
+ Integer.valueOf(imageDataIndex + 1), Integer.valueOf(imageDataArray.length));
} else {
string = createMsg(bundle.getString("Type_string"), fileTypeString(imageData.type));
}
typeLabel.setText(string);
string = createMsg(bundle.getString("Size_value"),
- new Object[] {Integer.valueOf(imageData.width),
- Integer.valueOf(imageData.height)});
+ Integer.valueOf(imageData.width), Integer.valueOf(imageData.height));
sizeLabel.setText(string);
string = createMsg(bundle.getString("Depth_value"),
- new Object[] {Integer.valueOf(imageData.depth), Integer.valueOf(display.getDepth())});
+ Integer.valueOf(imageData.depth), Integer.valueOf(display.getDepth()));
depthLabel.setText(string);
string = createMsg(bundle.getString("Transparent_pixel_value"), pixelInfo(imageData.transparentPixel));
@@ -1680,27 +1677,25 @@ public class ImageAnalyzer {
timeToLoadLabel.setText(string);
string = createMsg(bundle.getString("Animation_size_value"),
- new Object[] {Integer.valueOf(loader.logicalScreenWidth),
- Integer.valueOf(loader.logicalScreenHeight)});
+ Integer.valueOf(loader.logicalScreenWidth), Integer.valueOf(loader.logicalScreenHeight));
screenSizeLabel.setText(string);
string = createMsg(bundle.getString("Background_pixel_value"), pixelInfo(loader.backgroundPixel));
backgroundPixelLabel.setText(string);
string = createMsg(bundle.getString("Image_location_value"),
- new Object[] {Integer.valueOf(imageData.x), Integer.valueOf(imageData.y)});
+ Integer.valueOf(imageData.x), Integer.valueOf(imageData.y));
locationLabel.setText(string);
string = createMsg(bundle.getString("Disposal_value"),
- new Object[] {Integer.valueOf(imageData.disposalMethod),
- disposalString(imageData.disposalMethod)});
+ Integer.valueOf(imageData.disposalMethod), disposalString(imageData.disposalMethod));
disposalMethodLabel.setText(string);
int delay = imageData.delayTime * 10;
int delayUsed = visibleDelay(delay);
if (delay != delayUsed) {
string = createMsg(bundle.getString("Delay_value"),
- new Object[] {Integer.valueOf(delay), Integer.valueOf(delayUsed)});
+ Integer.valueOf(delay), Integer.valueOf(delayUsed));
} else {
string = createMsg(bundle.getString("Delay_used"), Integer.valueOf(delay));
}
@@ -1722,17 +1717,17 @@ public class ImageAnalyzer {
string = createMsg(
bundle.getString("Pixel_data_value"),
- new Object[] {
Integer.valueOf(imageData.bytesPerLine),
Integer.valueOf(imageData.scanlinePad),
depthInfo(imageData.depth),
(imageData.alphaData != null && imageData.alphaData.length > 0) ?
- bundle.getString("Scroll_for_alpha") : "" });
+ bundle.getString("Scroll_for_alpha") : "");
dataLabel.setText(string);
String data = dataHexDump(dataText.getLineDelimiter());
dataText.setText(data);
+ ArrayList<StyleRange> ranges = new ArrayList<>();
// bold the first column all the way down
int index = 0;
while((index = data.indexOf(':', index+1)) != -1) {
@@ -1742,8 +1737,9 @@ public class ImageAnalyzer {
start = index - ALPHA_CHARS;
length = ALPHA_CHARS;
}
- dataText.setStyleRange(new StyleRange(start, length, dataText.getForeground(), dataText.getBackground(), SWT.BOLD));
+ ranges.add(new StyleRange(start, length, dataText.getForeground(), dataText.getBackground(), SWT.BOLD));
}
+ if(!ranges.isEmpty()) dataText.setStyleRanges(ranges.toArray(new StyleRange[0]));
statusLabel.setText("");
@@ -2083,7 +2079,7 @@ public class ImageAnalyzer {
*/
void showErrorDialog(String operation, String filename, Throwable e) {
MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
- String message = createMsg(bundle.getString("Error"), new String[] {operation, filename});
+ String message = createMsg(bundle.getString("Error"), operation, filename);
String errorMessage = "";
if (e != null) {
if (e instanceof SWTException) {
@@ -2168,16 +2164,13 @@ public class ImageAnalyzer {
Object[] args = {Integer.valueOf(depth), ""};
switch (depth) {
case 1:
- args[1] = createMsg(bundle.getString("Multi_pixels"),
- new Object[] {Integer.valueOf(8), " [01234567]"});
+ args[1] = createMsg(bundle.getString("Multi_pixels"), Integer.valueOf(8), " [01234567]");
break;
case 2:
- args[1] = createMsg(bundle.getString("Multi_pixels"),
- new Object[] {Integer.valueOf(4), "[00112233]"});
+ args[1] = createMsg(bundle.getString("Multi_pixels"), Integer.valueOf(4), "[00112233]");
break;
case 4:
- args[1] = createMsg(bundle.getString("Multi_pixels"),
- new Object[] {Integer.valueOf(2), "[00001111]"});
+ args[1] = createMsg(bundle.getString("Multi_pixels"), Integer.valueOf(2), "[00001111]");
break;
case 8:
args[1] = bundle.getString("One_byte");
@@ -2353,13 +2346,9 @@ public class ImageAnalyzer {
compressionRatioLabel.setEnabled(false);
}
- static String createMsg(String msg, Object[] args) {
+ static String createMsg(String msg, Object... args) {
MessageFormat formatter = new MessageFormat(msg);
return formatter.format(args);
}
- static String createMsg(String msg, Object arg) {
- MessageFormat formatter = new MessageFormat(msg);
- return formatter.format(new Object[]{arg});
- }
}
diff --git a/examples/org.eclipse.swt.snippets/previews/Snippet379.png b/examples/org.eclipse.swt.snippets/previews/Snippet379.png
new file mode 100644
index 0000000000..ee1cc11fbb
--- /dev/null
+++ b/examples/org.eclipse.swt.snippets/previews/Snippet379.png
Binary files differ
diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet154.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet154.java
index 3b53f20a1b..cc37286975 100644
--- a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet154.java
+++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet154.java
@@ -54,7 +54,7 @@ public class Snippet154 {
/* Create and setting up frame */
Frame frame = SWT_AWT.new_Frame(composite);
- Panel panel = new Panel(new BorderLayout()) {
+ Panel panel = new Panel(new java.awt.BorderLayout()) {
@Override
public void update(java.awt.Graphics g) {
/* Do not erase the background */
@@ -84,7 +84,7 @@ public class Snippet154 {
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.createDefaultColumnsFromModel();
JScrollPane scrollPane = new JScrollPane(table);
- contentPane.setLayout(new BorderLayout());
+ contentPane.setLayout(new java.awt.BorderLayout());
contentPane.add(scrollPane);
shell.open();
diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet246.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet246.java
index a8eb74443c..331228deac 100644
--- a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet246.java
+++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet246.java
@@ -21,32 +21,51 @@ package org.eclipse.swt.snippets;
*/
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class Snippet246 {
+ static Display display;
public static void main(String[] args) {
- Display display = new Display();
- Font font = new Font(display, "Comic Sans MS", 24, SWT.BOLD);
- Image image = new Image(display, 87, 48);
+ display = new Display();
+ Shell shell = new Shell(display);
+ shell.setText("Snippet 246");
+ GridLayout layout = new GridLayout(2, false);
+ shell.setLayout(layout);
+ createImage();
+
+ String executionPath = System.getProperty("user.dir");
+ Label label = new Label(shell, SWT.WRAP);
+ label.setText("File created as: " + executionPath.replace("\\", "/")+"/swt.png");
+ shell.pack();
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+ }
+
+ private static void createImage() {
+ Font font = new Font(display, "Comic Sans MS", 48, SWT.BOLD);
+ Image image = new Image(display, 174, 96);
GC gc = new GC(image);
gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
gc.fillRectangle(image.getBounds());
gc.setFont(font);
gc.setForeground(display.getSystemColor(SWT.COLOR_RED));
- gc.drawString("S", 3, 0);
+ gc.drawString("S", 3, 10);
gc.setForeground(display.getSystemColor(SWT.COLOR_GREEN));
- gc.drawString("W", 25, 0);
+ gc.drawString("W", 50, 10);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE));
- gc.drawString("T", 62, 0);
+ gc.drawString("T", 124, 10);
gc.dispose();
ImageLoader loader = new ImageLoader();
- loader.data = new ImageData[] {image.getImageData()};
+ loader.data = new ImageData[] { image.getImageData() };
loader.save("swt.png", SWT.IMAGE_PNG);
-
image.dispose();
font.dispose();
- display.dispose();
}
}
diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet337.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet337.java
index 669bef4745..357afaff54 100644
--- a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet337.java
+++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet337.java
@@ -64,7 +64,7 @@ public static void main(String args[]) {
mainPanel.add(new JTextField("a JTextField"));
mainPanel.add(launchBrowserButton);
- mainFrame.getContentPane().add(mainPanel, BorderLayout.CENTER);
+ mainFrame.getContentPane().add(mainPanel, java.awt.BorderLayout.CENTER);
mainFrame.pack();
mainFrame.setVisible(true);
});
diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet379.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet379.java
new file mode 100644
index 0000000000..1a865ce39b
--- /dev/null
+++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet379.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Christoph Läubrich and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.snippets;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+/**
+ * This snippet demonstrates the usage of {@link BorderLayout}
+ */
+public class Snippet379 {
+
+ public static void main(String[] args) {
+
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setText("Border Layout Snippet");
+ BorderLayout layout = new BorderLayout();
+ layout.marginHeight = 16;
+ layout.marginWidth = 8;
+ layout.spacing = 4;
+ layout.controlSpacing = 2;
+ layout.type = SWT.VERTICAL;
+ shell.setBackground(display.getSystemColor(SWT.COLOR_CYAN));
+ shell.setLayout(layout);
+ shell.setSize(800, 600);
+ region(new Button(shell, SWT.PUSH), SWT.TOP).setText("North 1");
+ region(new Button(shell, SWT.PUSH), SWT.TOP).setText("North 2");
+ region(new Button(shell, SWT.PUSH), SWT.BOTTOM).setText("South 1");
+ region(new Button(shell, SWT.PUSH), SWT.BOTTOM).setText("South 2");
+ region(new Button(shell, SWT.PUSH), SWT.LEFT).setText("West 1");
+ region(new Button(shell, SWT.PUSH), SWT.LEFT).setText("West 2");
+ region(new Button(shell, SWT.PUSH), SWT.RIGHT).setText("East 1");
+ region(new Button(shell, SWT.PUSH), SWT.RIGHT).setText("East 2");
+ new Text(shell, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL).setText("Center 1");
+ new Text(shell, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL).setText("Center 2");
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+ display.dispose();
+ }
+
+ private static <C extends Control> C region(C control, int region) {
+ control.setLayoutData(new BorderData(region));
+ return control;
+ }
+
+}
diff --git a/features/org.eclipse.swt.tools.feature/feature.xml b/features/org.eclipse.swt.tools.feature/feature.xml
index 682f874a75..662c6510c9 100644
--- a/features/org.eclipse.swt.tools.feature/feature.xml
+++ b/features/org.eclipse.swt.tools.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="org.eclipse.swt.tools.feature"
label="%featureName"
- version="3.108.300.qualifier"
+ version="3.108.400.qualifier"
provider-name="%providerName"
license-feature="org.eclipse.license"
license-feature-version="0.0.0">
diff --git a/features/org.eclipse.swt.tools.feature/pom.xml b/features/org.eclipse.swt.tools.feature/pom.xml
index a86a3d3bd3..babc7c8373 100644
--- a/features/org.eclipse.swt.tools.feature/pom.xml
+++ b/features/org.eclipse.swt.tools.feature/pom.xml
@@ -15,12 +15,12 @@
<parent>
<artifactId>eclipse.platform.swt</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<groupId>org.eclipse.swt.tools.feature</groupId>
<artifactId>org.eclipse.swt.tools.feature</artifactId>
- <version>3.108.300-SNAPSHOT</version>
+ <version>3.108.400-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
<build>
<plugins>
diff --git a/local-build/local-build-parent/pom.xml b/local-build/local-build-parent/pom.xml
index 45e0db0d78..424afe267b 100644
--- a/local-build/local-build-parent/pom.xml
+++ b/local-build/local-build-parent/pom.xml
@@ -14,7 +14,7 @@
<parent>
<artifactId>eclipse.platform.swt</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
diff --git a/local-build/org.eclipse.swt.fragments.localbuild/pom.xml b/local-build/org.eclipse.swt.fragments.localbuild/pom.xml
index 7fb02bf540..4014fe2bba 100644
--- a/local-build/org.eclipse.swt.fragments.localbuild/pom.xml
+++ b/local-build/org.eclipse.swt.fragments.localbuild/pom.xml
@@ -14,7 +14,7 @@
<parent>
<artifactId>eclipse.platform.swt</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
diff --git a/pom.xml b/pom.xml
index fb5e89d2c8..bdc9209a42 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,7 +16,7 @@
<parent>
<groupId>org.eclipse</groupId>
<artifactId>eclipse-platform-parent</artifactId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../eclipse-platform-parent</relativePath>
</parent>
diff --git a/tests/org.eclipse.swt.tests.cocoa/ManualTests/org/eclipse/swt/tests/cocoa/snippets/Bug569088_macOS_RadioButtonNotRendered.java b/tests/org.eclipse.swt.tests.cocoa/ManualTests/org/eclipse/swt/tests/cocoa/snippets/Bug569088_macOS_RadioButtonNotRendered.java
new file mode 100644
index 0000000000..b7194458e4
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.cocoa/ManualTests/org/eclipse/swt/tests/cocoa/snippets/Bug569088_macOS_RadioButtonNotRendered.java
@@ -0,0 +1,42 @@
+package org.eclipse.swt.tests.cocoa.snippets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class Bug569088_macOS_RadioButtonNotRendered {
+
+ public static void main(String[] args) {
+ final Display display = new Display();
+
+ final Shell shell = new Shell(display);
+ shell.setSize(300, 300);
+ shell.setLayout(new GridLayout(2, true));
+
+ final Button button1 = new Button(shell, SWT.RADIO | SWT.WRAP);
+ button1.setText("Button text 1 is loooooooong");
+ button1.setForeground(display.getSystemColor(SWT.COLOR_RED));
+ button1.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
+ button1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ final Button button2 = new Button(shell, SWT.CHECK | SWT.WRAP);
+ button2.setText("Button text 2 is loooooooong");
+ button2.setForeground(display.getSystemColor(SWT.COLOR_RED));
+ button2.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
+ button2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ shell.open();
+ System.err.println(button1.getBounds()); // Rectangle {5, 5, 142, 0}
+ System.err.println(button2.getBounds()); // Rectangle {152, 10, 142, 0}
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+ display.dispose();
+ }
+
+}
diff --git a/tests/org.eclipse.swt.tests.cocoa/pom.xml b/tests/org.eclipse.swt.tests.cocoa/pom.xml
index b6cdd784e0..3a629b7c51 100644
--- a/tests/org.eclipse.swt.tests.cocoa/pom.xml
+++ b/tests/org.eclipse.swt.tests.cocoa/pom.xml
@@ -14,7 +14,7 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
diff --git a/tests/org.eclipse.swt.tests.gtk/META-INF/MANIFEST.MF b/tests/org.eclipse.swt.tests.gtk/META-INF/MANIFEST.MF
index f5d046b2e7..e492847919 100644
--- a/tests/org.eclipse.swt.tests.gtk/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.swt.tests.gtk/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.swt.tests.gtk
-Bundle-Version: 3.108.0.qualifier
+Bundle-Version: 3.108.100.qualifier
Bundle-Vendor: %providerName
Require-Bundle: org.junit;bundle-version="4.12.0",
org.eclipse.swt
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug525946_DownloadFunction.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug525946_DownloadFunction.java
index 9079cf9e5b..0a99bae100 100644
--- a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug525946_DownloadFunction.java
+++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug525946_DownloadFunction.java
@@ -34,8 +34,8 @@ public class Bug525946_DownloadFunction {
shell.setBounds(10, 10, 400, 400);
shell.setLayout(new FillLayout());
final Browser browser = new Browser(shell, SWT.NONE);
-// browser.setUrl("http://download.eclipse.org/eclipse/downloads/drops4/I20180416-2000/download.php?dropFile=eclipse-test-framework-I20180416-2000.zip"); // 2.3 mb
- browser.setUrl("http://download.eclipse.org/tools/orbit/downloads/drops/R20170516192513/orbit-buildrepo-R20170516192513.zip"); // 400mb
+// browser.setUrl("https://download.eclipse.org/eclipse/downloads/drops4/I20180416-2000/download.php?dropFile=eclipse-test-framework-I20180416-2000.zip"); // 2.3 mb
+ browser.setUrl("https://download.eclipse.org/tools/orbit/downloads/drops/R20170516192513/orbit-buildrepo-R20170516192513.zip"); // 400mb
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug579257_new_webkit_window.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug579257_new_webkit_window.java
new file mode 100644
index 0000000000..993cfe4ade
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug579257_new_webkit_window.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Simeon Andreev and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.tests.gtk.snippets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.VisibilityWindowAdapter;
+import org.eclipse.swt.browser.WindowEvent;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+public class Bug579257_new_webkit_window {
+
+ public static void main(String[] args) {
+ String webPageHtml = "<html><head></head><body>"
+ + "<a href=\"https://www.eclipse.org\" target=\"new\">link with target property set to \"new\"</a>"
+ + "</body></html>";
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setSize(600, 400);
+ shell.setLayout(new FillLayout());
+ shell.setText("Bug579257_new_webkit_window");
+
+ Composite composite = new Composite(shell, SWT.NONE);
+ composite.setLayout(new FillLayout());
+
+ Browser b = new Browser(composite, SWT.NONE);
+ b.setText(webPageHtml);
+ b.addOpenWindowListener(event -> {
+ Shell newWindowShell = new Shell(shell, SWT.SHELL_TRIM);
+ newWindowShell.setLayout(new FillLayout());
+ Browser newWindowBrowser = new Browser(newWindowShell, SWT.NONE);
+ newWindowBrowser.addVisibilityWindowListener(new VisibilityWindowAdapter() {
+ @Override
+ public void show(WindowEvent e) {
+ newWindowShell.setSize(400, 200);
+ newWindowShell.open();
+ }
+ });
+ event.browser = newWindowBrowser;
+ });
+
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+ }
+} \ No newline at end of file
diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug579283_TestToolbarOverflow_itemEnablement.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug579283_TestToolbarOverflow_itemEnablement.java
new file mode 100644
index 0000000000..3826a9bafc
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug579283_TestToolbarOverflow_itemEnablement.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Simeon Andreev and others. All rights reserved.
+ * The contents of this file are made available under the terms
+ * of the GNU Lesser General Public License (LGPL) Version 2.1 that
+ * accompanies this distribution (lgpl-v21.txt). The LGPL is also
+ * available at http://www.gnu.org/licenses/lgpl.html. If the version
+ * of the LGPL at http://www.gnu.org is different to the version of
+ * the LGPL accompanying this distribution and there is any conflict
+ * between the two license versions, the terms of the LGPL accompanying
+ * this distribution shall govern.
+ *
+ * Contributors:
+ * Simeon Andreev - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.tests.gtk.snippets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+/**
+ * Description: Toolbar items in a toolbar overflow submenu (enabled with style flag {@link SWT.WRAP})
+ * do not show correct image enablement.
+ * <p>
+ * Steps to reproduce:
+ * <ol>
+ * <li>Run the snippet.</li>
+ * <li>Resize the {@link Shell}, so that only some of the icons are visible.</li>
+ * <li>Mouse-over the first toolbar button, which is enabled.</li>
+ * <li>The overflow button (downward arrow) should be visible to the right now.</li>
+ * <li>Click it, observe that the disabled buttons don't have disabled images.</li>
+ * <li>Click one of the overflow submenu items.</li>
+ * <li>Show the overflow menu again, observe that the image of the clicked item is not changed.</li>
+ * </ol>
+ * </p>
+ * Expected results: Images of disabled buttons should appear grayed out.
+ * Images should change on overflow submenu item click.
+ * Text and tooltip of an overflow submenu item should also change on click.
+ * Clicking on overflow submenu items should result in only 1 widget selected notification (see console output).
+ * Actual results: Images of disabled buttons in the overflow submenu are not grayed out.
+ * Images are not updated on overflow submenu item click.
+ */
+public class Bug579283_TestToolbarOverflow_itemEnablement {
+
+ public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setText("Bug 579283 test enablement of overflowing toolbar items");
+ shell.setLayout(new FillLayout());
+ Composite c1 = new Composite(shell, SWT.BORDER);
+ c1.setLayout(new FillLayout());
+
+ ToolBar toolBar = new ToolBar(c1, SWT.WRAP);
+ toolBar.setLayout(new RowLayout());
+
+ Image[] icons = {
+ display.getSystemImage(SWT.ICON_INFORMATION),
+ display.getSystemImage(SWT.ICON_WARNING),
+ display.getSystemImage(SWT.ICON_ERROR),
+ };
+
+ for (int i = 0; i < 8; ++i) {
+ final int index = i;
+ ToolItem item = new ToolItem(toolBar, SWT.CHECK);
+ item.setImage(icons[0]);
+ item.setText(String.valueOf(i));
+ item.setToolTipText(String.valueOf(i));
+ if (i % 2 == 0) {
+ item.setEnabled(false);
+ }
+ item.addSelectionListener(new SelectionAdapter() {
+ int iconIndex = 0;
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ System.out.println("Toolbar button " + index + " clicked!");
+ ++iconIndex;
+ item.setImage(icons[iconIndex % icons.length]);
+ item.setText(String.valueOf(index) + "[" + iconIndex + "]");
+ item.setToolTipText(String.valueOf(index) + "[" + iconIndex + "]");
+ }
+ });
+ }
+
+ shell.setSize(500, 100);
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ display.dispose();
+ }
+
+} \ No newline at end of file
diff --git a/tests/org.eclipse.swt.tests.gtk/pom.xml b/tests/org.eclipse.swt.tests.gtk/pom.xml
index 8e4d84a5d9..dfd787edcb 100644
--- a/tests/org.eclipse.swt.tests.gtk/pom.xml
+++ b/tests/org.eclipse.swt.tests.gtk/pom.xml
@@ -14,12 +14,12 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
<artifactId>org.eclipse.swt.tests.gtk</artifactId>
- <version>3.108.0-SNAPSHOT</version>
+ <version>3.108.100-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
<code.ignoredWarnings>${tests.ignoredWarnings}</code.ignoredWarnings>
diff --git a/tests/org.eclipse.swt.tests.win32/pom.xml b/tests/org.eclipse.swt.tests.win32/pom.xml
index 49a3c0627a..37bcbbc7cc 100644
--- a/tests/org.eclipse.swt.tests.win32/pom.xml
+++ b/tests/org.eclipse.swt.tests.win32/pom.xml
@@ -14,7 +14,7 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java
index 3bbc19a203..4daf9d8692 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java
@@ -2162,6 +2162,47 @@ public void test_BrowserFunction_callback_afterPageReload() {
assertTrue(message, passed);
}
+@Test
+public void test_BrowserFunction_multiprocess() {
+ // Test that BrowserFunctions work in multiple Browser instances simultaneously.
+ Browser browser1 = new Browser(shell, SWT.NONE);
+ Browser browser2 = new Browser(shell, SWT.NONE);
+
+ class JavaFunc extends BrowserFunction {
+ JavaFunc(Browser browser) {
+ super(browser, "javaFunc");
+ }
+
+ @Override
+ public Object function(Object[] arguments) {
+ return arguments[0];
+ }
+ }
+ new JavaFunc(browser1);
+ new JavaFunc(browser2);
+ assertEquals("value1", browser1.evaluate("return javaFunc('value1')"));
+ assertEquals("value2", browser2.evaluate("return javaFunc('value2')"));
+
+ // Ensure that navigation to a different page preserves BrowserFunctions.
+ int[] completed = new int[1];
+ ProgressListener listener = new ProgressAdapter() {
+ @Override
+ public void completed(ProgressEvent event) {
+ completed[0]++;
+ }
+ };
+ browser1.addProgressListener(listener);
+ browser2.addProgressListener(listener);
+ browser1.setText("<body>new_page1");
+ browser2.setText("<body>new_page2");
+ waitForPassCondition(() -> completed[0] == 2);
+ assertEquals("value1", browser1.evaluate("return javaFunc('value1')"));
+ assertEquals("value2", browser2.evaluate("return javaFunc('value2')"));
+
+ browser1.dispose();
+ browser2.dispose();
+}
+
/* custom */
/**
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_TextLayout.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_TextLayout.java
index 174a988728..e91b80a6ba 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_TextLayout.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_TextLayout.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.fail;
import java.util.Arrays;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
@@ -1180,4 +1181,66 @@ public void test_bug23406_longLines() {
check(bestProgramInThai, 1000);
}
+@Test
+public void test_Bug579335_win32_StyledText_LongLine() {
+ if (!SwtTestUtil.isWindows) {
+ // TODO This test was written for the platform specific parts of TextLayout and
+ // on Linux (and possibly mac)
+ // the size of images needed to run the tests causes failures.
+ if (SwtTestUtil.verbose) {
+ System.out.println(
+ "Excluded test_Bug579335_win32_StyledText_LongLine(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_TextLayout).");
+ }
+ return;
+ }
+
+ Font font = null;
+ Image image = null;
+ TextLayout layout = null;
+
+ try {
+ font = new Font(display, SwtTestUtil.testFontName, 16, SWT.NORMAL);
+
+ layout = new TextLayout(display);
+ layout.setFont(font);
+ layout.setText("a".repeat(33000));
+ Color red = display.getSystemColor(SWT.COLOR_RED);
+ Color white = display.getSystemColor(SWT.COLOR_WHITE);
+ Color green = display.getSystemColor(SWT.COLOR_GREEN);
+ TextStyle redStyle = new TextStyle(font, red, white);
+ TextStyle greenStyle = new TextStyle(font, green, white);
+
+ image = draw(layout, SWT.DEFAULT);
+
+ layout.setStyle(redStyle, 7, 7);
+ layout.setStyle(greenStyle, 8, 8 + 32909 - 1);
+
+ image = draw(layout, SWT.DEFAULT);
+
+ // reset for next test
+ image.dispose();
+ layout.setStyle(null, 0, 33000 - 1);
+
+ layout.setStyle(greenStyle, 2, 2 + 16000 - 1);
+ image = draw(layout, SWT.DEFAULT);
+
+ // reset for next test
+ image.dispose();
+ layout.setStyle(null, 0, 33000 - 1);
+
+ layout.setStyle(redStyle, 0, 0 + 1 - 1);
+ layout.setStyle(greenStyle, 1, 1 + 32916 - 1);
+ image = draw(layout, SWT.DEFAULT);
+
+// SwtTestUtil.debugDisplayImage(image);
+ } finally {
+
+ if (layout != null)
+ layout.dispose();
+ if (image != null)
+ image.dispose();
+ if (font != null)
+ font.dispose();
+ }
+}
}
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_layout_BorderLayout.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_layout_BorderLayout.java
new file mode 100644
index 0000000000..e241a44bef
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_layout_BorderLayout.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Christoph Läubrich and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christoph Läubrich - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.tests.junit;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.BorderData;
+import org.eclipse.swt.layout.BorderLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Automated Test Suite for class {@link BorderLayout}
+ *
+ */
+public class Test_org_eclipse_swt_layout_BorderLayout {
+
+ Display display;
+
+ @Before
+ public void setUp() {
+ display = Display.getDefault();
+ }
+
+ public void tearDown() {
+ SwtTestUtil.processEvents();
+ display.dispose();
+ }
+
+ @Test
+ public void testControlExcluded() {
+ Shell shell = new Shell(display);
+ shell.setLayout(new BorderLayout());
+ shell.setSize(800, 600);
+ MockControl control = new MockControl(shell);
+ control.setLayoutData(new BorderData(SWT.NONE));
+ control.setBounds(0, 0, 100, 100);
+ shell.open();
+ SwtTestUtil.processEvents();
+ // the expectation is that the control is set to zero width/height
+ // even we have set a different size before...
+ Rectangle bounds = control.getBounds();
+ assertEquals(0, bounds.width);
+ assertEquals(0, bounds.height);
+ shell.dispose();
+ }
+
+ @Test
+ public void testHints() {
+ Shell shell = new Shell(display);
+ shell.setLayout(new BorderLayout());
+ shell.setSize(800, 600);
+ MockControl control = new MockControl(shell);
+ control.setLayoutData(new BorderData(SWT.TOP, 40, 50));
+ shell.open();
+ SwtTestUtil.processEvents();
+ // the expectation is that the hints are passed to the control
+ assertEquals(40, control.wHint);
+ assertEquals(50, control.hHint);
+ shell.dispose();
+ }
+
+ @Test
+ public void testControlLayout() {
+ Shell shell = new Shell(display);
+ shell.setLayout(new BorderLayout());
+ shell.setSize(800, 600);
+ MockControl topControl = new MockControl(shell);
+ topControl.reportedHeight = 10;
+ topControl.reportedWidth = 1000000;
+ MockControl bottomControl = new MockControl(shell);
+ bottomControl.reportedHeight = 20;
+ bottomControl.reportedWidth = 123;
+ MockControl leftControl = new MockControl(shell);
+ leftControl.reportedHeight = 5;
+ leftControl.reportedWidth = 50;
+ MockControl rightControl = new MockControl(shell);
+ rightControl.reportedHeight = 5;
+ rightControl.reportedWidth = 40;
+ MockControl centerControl = new MockControl(shell);
+ topControl.setLayoutData(new BorderData(SWT.TOP));
+ bottomControl.setLayoutData(new BorderData(SWT.BOTTOM));
+ leftControl.setLayoutData(new BorderData(SWT.LEFT));
+ rightControl.setLayoutData(new BorderData(SWT.RIGHT));
+ shell.open();
+ shell.layout();
+ SwtTestUtil.processEvents();
+ // the expectation is that the control at the north is at the top and has the
+ // size returned by computeSize but a width that is the width of the shell
+ Rectangle clientArea = shell.getClientArea();
+ Rectangle topBounds = topControl.getBounds();
+ assertEquals(0, topBounds.x);
+ assertEquals(0, topBounds.y);
+ assertEquals(clientArea.width, topBounds.width);
+ assertEquals(topControl.reportedHeight, topBounds.height);
+ // the expectation is that the control at the south is at the bottom and has
+ // the size returned by computeSize but a width that is the width of the shell
+ Rectangle bottomBounds = bottomControl.getBounds();
+ assertEquals(0, bottomBounds.x);
+ assertEquals(clientArea.height - bottomControl.reportedHeight, bottomBounds.y);
+ assertEquals(clientArea.width, bottomBounds.width);
+ assertEquals(bottomControl.reportedHeight, bottomBounds.height);
+ // the expectation is that the control at the west is placed left and has
+ // the size returned by computeSize but the height is that of the shell
+ // subtracting the height of the north/south controls
+ Rectangle leftBounds = leftControl.getBounds();
+ assertEquals(0, leftBounds.x);
+ assertEquals(topControl.reportedHeight, leftBounds.y);
+ assertEquals(leftControl.reportedWidth, leftBounds.width);
+ assertEquals(clientArea.height - topControl.reportedHeight - bottomControl.reportedHeight, leftBounds.height);
+ // the expectation is that the control at the east is placed right and has
+ // the size returned by computeSize but the height is that of the shell
+ // subtracting the height of the north/south controls
+ Rectangle rightBounds = rightControl.getBounds();
+ assertEquals(clientArea.width - rightControl.reportedWidth, rightBounds.x);
+ assertEquals(topControl.reportedHeight, rightBounds.y);
+ assertEquals(rightControl.reportedWidth, rightBounds.width);
+ assertEquals(clientArea.height - topControl.reportedHeight - bottomControl.reportedHeight, rightBounds.height);
+ // the center control should take the remaining size...
+ Rectangle centerBounds = centerControl.getBounds();
+ assertEquals(leftControl.reportedWidth, centerBounds.x);
+ assertEquals(topControl.reportedHeight, centerBounds.y);
+ assertEquals(clientArea.width - leftControl.reportedWidth - rightControl.reportedWidth, centerBounds.width);
+ assertEquals(clientArea.height - topControl.reportedHeight - bottomControl.reportedHeight, centerBounds.height);
+ shell.dispose();
+ }
+
+ private static final class MockControl extends Canvas {
+
+ private int wHint;
+ private int hHint;
+
+ private int reportedHeight = -1;
+ private int reportedWidth = -1;
+
+ public MockControl(Composite parent) {
+ super(parent, SWT.NONE);
+ setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLUE));
+ }
+
+ @Override
+ public Point computeSize(int wHint, int hHint, boolean changed) {
+ System.out.println(
+ "Test_org_eclipse_swt_layout_BorderLayout.MockControl.computeSize(" + wHint + "," + hHint + ")");
+ this.wHint = wHint;
+ this.hHint = hHint;
+ if (reportedHeight > 0 && reportedWidth > 0) {
+ return new Point(reportedWidth, reportedHeight);
+ }
+ return super.computeSize(wHint, hHint, changed);
+ }
+
+ }
+
+}
diff --git a/tests/org.eclipse.swt.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.swt.tests/META-INF/MANIFEST.MF
index 4b7dae65a7..78d2b616fd 100644
--- a/tests/org.eclipse.swt.tests/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.swt.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.swt.tests
-Bundle-Version: 3.106.1600.qualifier
+Bundle-Version: 3.106.1700.qualifier
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Export-Package: org.eclipse.swt.tests.junit,
diff --git a/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug456602_macOS_AIOOBE_Table_selectedRowIndex.java b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug456602_macOS_AIOOBE_Table_selectedRowIndex.java
new file mode 100644
index 0000000000..c161b26a22
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug456602_macOS_AIOOBE_Table_selectedRowIndex.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Syntevo and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Syntevo - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.swt.tests.manual;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+
+import java.util.Arrays;
+
+public final class Bug456602_macOS_AIOOBE_Table_selectedRowIndex {
+ public static void main(String[] args) {
+ final Display display = new Display();
+
+ final Shell shell = new Shell(display);
+ shell.setLayout(new GridLayout(1, true));
+
+ Label hint = new Label(shell, 0);
+ hint.setText(
+ "Bug 456602\n" +
+ "----------\n" +
+ "1) Use macOS\n" +
+ "2) Click 'Delete items' button\n" +
+ "3) Press left mouse button on last table item and HOLD the button\n" +
+ "4) When item is deleted, release the button\n" +
+ "5) Bug 456602: SWT will have an internal AIOOBE\n" +
+ "6) Bug 456602: More exceptions are reported if you set focus to\n" +
+ " Text beforehand and move the mouse after\n" +
+ "7) In real world, user would clicks faster, but crashes will\n" +
+ " still happen sometimes\n" +
+ "\n" +
+ "Bug 355200 and Bug 289483\n" +
+ "-------------------------\n" +
+ "Just to ensure that old workarounds are still working fine:\n" +
+ "1) Click any Table item when multiple items are selected\n" +
+ "2) SWT.Selection shall report clicked item\n" +
+ "3) The order shall be: SWT.MouseDown, SWT.Selection, SWT.MouseUp"
+ );
+
+ Table table = new Table(shell, SWT.BORDER | SWT.MULTI);
+ table.addListener(SWT.MouseDown, e -> {
+ System.out.println(System.currentTimeMillis() + " SWT.MouseDown: " + Arrays.toString(table.getSelectionIndices()));
+ });
+ table.addListener(SWT.MouseUp, e -> {
+ System.out.println(System.currentTimeMillis() + " SWT.MouseUp: " + Arrays.toString(table.getSelectionIndices()));
+ });
+ table.addListener(SWT.Selection, e -> {
+ System.out.println(System.currentTimeMillis() + " SWT.Selection: " + Arrays.toString(table.getSelectionIndices()));
+ });
+
+ for (int iItem = 0; iItem < 10; iItem++) {
+ new TableItem(table, 0).setText("Item #" + iItem);
+ }
+ table.selectAll();
+
+ Button button = new Button(shell, SWT.PUSH);
+ button.setText("Delete items after 2000ms");
+ button.addListener(SWT.Selection, e -> {
+ display.timerExec(2000, () -> {
+ table.setItemCount(table.getItemCount() / 2);
+ });
+ });
+
+ new Text(shell, 0).setText("I'm a text field");
+
+ shell.pack();
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ display.dispose();
+ }
+}
diff --git a/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug546935_TableFlickeringResizingColumns.java b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug546935_TableFlickeringResizingColumns.java
new file mode 100644
index 0000000000..fd759c4bfa
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug546935_TableFlickeringResizingColumns.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Syntevo and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Syntevo - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.swt.tests.manual;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public class Bug546935_TableFlickeringResizingColumns {
+ public static void main(String[] args) {
+ final Display display = new Display();
+ final Shell shell = new Shell(display);
+ shell.setLayout(new GridLayout(1, true));
+
+ final Label hint = new Label(shell, 0);
+ hint.setText(
+ "1) Run on Windows\n" +
+ "2) Choose a column where header is wider than items\n" +
+ "3) Double-click the header separator to auto-adjust column size\n" +
+ "4) Bug 546935: there is flickering even though column size doesn't change"
+ );
+
+ final Table table = new Table(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
+ table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ table.setHeaderVisible(true);
+
+ String[] columns = {
+ "column",
+ "header is longer"
+ };
+
+ String[] items = {
+ "item is longer",
+ "item"
+ };
+
+ for (int iColumn = 0; iColumn < columns.length * 3; iColumn++) {
+ final TableColumn tableColumn = new TableColumn(table, 0);
+ tableColumn.setText(columns[iColumn % columns.length]);
+ tableColumn.setWidth(100);
+ }
+
+ for (int iItem = 0; iItem < 100; iItem++) {
+ TableItem item = new TableItem(table, 0);
+ for (int iColumn = 0; iColumn < table.getColumnCount(); iColumn++) {
+ item.setText(iColumn, items[iColumn % columns.length]);
+ }
+ }
+
+ // 'MeasureItem' is required to reproduce.
+ table.addListener(SWT.MeasureItem, event -> {
+ event.width = 35;
+ });
+
+ // Debugging code, not needed to reproduce
+ {
+ final int[] itemsMeasured = new int[1];
+ final int[] itemsPainted = new int[1];
+ table.addListener(SWT.MeasureItem, event -> {
+ itemsMeasured[0]++;
+ });
+ table.addListener(SWT.PaintItem, event -> {
+ itemsPainted[0]++;
+ });
+ table.addListener(SWT.Paint, event -> {
+ System.out.format("Measured=%d Painted=%d%n", itemsMeasured[0], itemsPainted[0]);
+ itemsMeasured[0] = 0;
+ itemsPainted[0] = 0;
+ });
+ }
+
+ Button btnPackColumn = new Button(shell, SWT.PUSH);
+ btnPackColumn.setText("Pack columns");
+ btnPackColumn.addListener(SWT.Selection, e -> {
+ for (int iColumn = 0; iColumn < table.getColumnCount(); iColumn++) {
+ table.getColumn(iColumn).pack();
+ }
+ });
+
+ shell.setSize(800, 340);
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+ display.dispose();
+ }
+}
diff --git a/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577129_Win11_NoButtonArrows.java b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577129_Win11_NoButtonArrows.java
new file mode 100644
index 0000000000..1958c3eee0
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577129_Win11_NoButtonArrows.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Syntevo and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Syntevo - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.swt.tests.manual;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public final class Bug577129_Win11_NoButtonArrows {
+ public static void main(String[] args) {
+ final Display display = new Display();
+ final Shell shell = new Shell(display);
+ shell.setLayout (new GridLayout (1, true));
+
+ Label hint = new Label (shell, 0);
+ hint.setText (
+ "1) Run on Win11 (Win10 is not enough)\n" +
+ "2) Bug 577129: Enabled buttons don't show arrows"
+ );
+
+ Composite composite = new Composite(shell, 0);
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ composite.setLayout(new GridLayout (5, true));
+
+ Button button;
+
+ new Label(composite, 0).setText("");
+ new Label(composite, 0).setText("UP");
+ new Label(composite, 0).setText("DOWN");
+ new Label(composite, 0).setText("LEFT");
+ new Label(composite, 0).setText("RIGHT");
+
+ for (int isEnabled = 0; isEnabled < 2; isEnabled++) {
+ if (isEnabled != 0) {
+ new Label(composite, 0).setText("Enabled");
+ } else {
+ new Label(composite, 0).setText("Disabled");
+ }
+
+ button = new Button(composite, SWT.ARROW | SWT.UP);
+ if (isEnabled == 0) {
+ button.setEnabled(false);
+ }
+
+ button = new Button(composite, SWT.ARROW | SWT.DOWN);
+ if (isEnabled == 0) {
+ button.setEnabled(false);
+ }
+
+ button = new Button(composite, SWT.ARROW | SWT.LEFT);
+ if (isEnabled == 0) {
+ button.setEnabled(false);
+ }
+
+ button = new Button(composite, SWT.ARROW | SWT.RIGHT);
+ if (isEnabled == 0) {
+ button.setEnabled(false);
+ }
+ }
+
+ shell.pack();
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ display.dispose();
+ }
+}
diff --git a/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577878_GTK_TreeTable_NoDragImageWithPaintItem.java b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577878_GTK_TreeTable_NoDragImageWithPaintItem.java
new file mode 100644
index 0000000000..028e5c5cb6
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577878_GTK_TreeTable_NoDragImageWithPaintItem.java
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 Syntevo and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Syntevo - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.swt.tests.manual;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public final class Bug577878_GTK_TreeTable_NoDragImageWithPaintItem {
+ static final int NUM_ROWS = 100;
+ static final int NUM_COLS = 2;
+ static final int IMG_CX = 22;
+ static final int IMG_CY = 16;
+
+ static String makeItemText(int iRow, int iCol) {
+ return "Item#" + iRow + ":" + iCol;
+ }
+
+ static Image makeItemImage(Device device, int iRow) {
+ Image image = new Image(device, IMG_CX, IMG_CY);
+ GC gc = new GC(image);
+ gc.setBackground(new Color(100,255,100));
+ gc.fillRectangle(0, 0, IMG_CX-1, IMG_CY-1);
+ gc.drawRectangle(0, 0, IMG_CX-1, IMG_CY-1);
+
+ String text = Integer.toString(iRow);
+ Point textSize = gc.stringExtent(text);
+ gc.drawText(text, (IMG_CX - textSize.x) / 2, (IMG_CY - textSize.y) / 2);
+
+ gc.dispose();
+ return image;
+ }
+
+ static void paintItem(Event event, Image image, int iRow) {
+ if (image != null) {
+ event.x += 2;
+ int y = event.y + (event.height - image.getBounds().height) / 2;
+ event.gc.drawImage(image, event.x, y);
+ event.x += image.getBounds().width;
+ }
+
+ event.x += 2;
+ String text = makeItemText(iRow, event.index);
+ Point textSize = event.gc.stringExtent(text);
+ int y = event.y + (event.height - textSize.y) / 2;
+ event.gc.drawString (text, event.x, y, true);
+ }
+
+ static void createTable(Composite parent, boolean isCustomPaint, boolean isImages) {
+ Table control = new Table (parent, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
+ control.setLayoutData (new GridData (SWT.FILL, SWT.FILL, true, true));
+
+ control.setHeaderVisible (true);
+ for (int iColumn = 0; iColumn < NUM_COLS; iColumn++) {
+ TableColumn column = new TableColumn (control, 0);
+ column.setText ("Col#" + iColumn);
+ column.setWidth (120);
+ }
+
+ control.setItemCount (NUM_ROWS);
+
+ if (isImages) {
+ for (int iItem = 0; iItem < NUM_ROWS; iItem++) {
+ control.getItem(iItem).setImage(makeItemImage(parent.getDisplay(), iItem));
+ }
+ }
+
+ if (isCustomPaint) {
+ control.addListener (SWT.MeasureItem, e -> {
+ e.width = 120;
+ e.height = 20;
+ });
+
+ control.addListener (SWT.EraseItem, e -> {
+ e.detail &= ~SWT.FOREGROUND;
+ });
+
+ control.addListener (SWT.PaintItem, e -> {
+ TableItem item = (TableItem) e.item;
+ int iRow = item.getParent ().indexOf (item);
+ paintItem(e, item.getImage(), iRow);
+ });
+ } else {
+ for (int iRow = 0; iRow < NUM_ROWS; iRow++) {
+ for (int iCol = 0; iCol < NUM_COLS; iCol++) {
+ control.getItem (iRow).setText (iCol, makeItemText(iRow, iCol));
+ }
+ }
+ }
+
+ DragSource dragSource = new DragSource (control, DND.DROP_MOVE | DND.DROP_COPY);
+ dragSource.setTransfer (TextTransfer.getInstance ());
+ dragSource.addDragListener (new DragSourceAdapter ());
+ }
+
+ static void createTree(Composite parent, boolean isCustomPaint, boolean isImages) {
+ Tree control = new Tree (parent, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
+ control.setLayoutData (new GridData (SWT.FILL, SWT.FILL, true, true));
+
+ control.setHeaderVisible (true);
+ for (int iColumn = 0; iColumn < NUM_COLS; iColumn++) {
+ TreeColumn column = new TreeColumn (control, 0);
+ column.setText ("Col#" + iColumn);
+ column.setWidth (120);
+ }
+
+ control.setItemCount (NUM_ROWS);
+
+ if (isImages) {
+ for (int iItem = 0; iItem < NUM_ROWS; iItem++) {
+ control.getItem(iItem).setImage(makeItemImage(parent.getDisplay(), iItem));
+ }
+ }
+
+ if (isCustomPaint) {
+ control.addListener (SWT.MeasureItem, e -> {
+ e.width = 120;
+ e.height = 20;
+ });
+
+ control.addListener (SWT.EraseItem, e -> {
+ e.detail &= ~SWT.FOREGROUND;
+ });
+
+ control.addListener (SWT.PaintItem, e -> {
+ TreeItem item = (TreeItem) e.item;
+ TreeItem parentItem = item.getParentItem ();
+ int iRow = (parentItem != null) ? parentItem.indexOf (item) : item.getParent ().indexOf (item);
+ paintItem(e, item.getImage(), iRow);
+ });
+ } else {
+ for (int iRow = 0; iRow < NUM_ROWS; iRow++) {
+ for (int iCol = 0; iCol < NUM_COLS; iCol++) {
+ control.getItem (iRow).setText (iCol, makeItemText(iRow, iCol));
+ }
+ }
+ }
+
+ TreeItem child = new TreeItem (control.getItem(1), 0);
+ if (!isCustomPaint) {
+ for (int iCol = 0; iCol < NUM_COLS; iCol++) {
+ child.setText (iCol, makeItemText(0, iCol));
+ }
+ }
+
+ DragSource dragSource = new DragSource (control, DND.DROP_MOVE | DND.DROP_COPY);
+ dragSource.setTransfer (TextTransfer.getInstance ());
+ dragSource.addDragListener (new DragSourceAdapter ());
+ }
+
+ public static void main(String[] args) {
+ final Display display = new Display();
+ final Shell shell = new Shell(display);
+ shell.setLayout (new GridLayout (1, true));
+
+ Label hint = new Label(shell, 0);
+ hint.setText (
+ "1) Run on GTK\n" +
+ "2) Drag rows from regular Table/Tree - there will be a drag image\n" +
+ "3) Bug 577878: Table/Tree with SWT.PaintItem do not have drag image\n" +
+ "\n" +
+ "Patch v2:\n" +
+ "4) Bug 577878 v2: Tree/Table with image should not have empty space\n" +
+ " to the left of the item\n" +
+ "5) Bug 579395: Tree with images and PaintItem overpaints expanders\n" +
+ " Old bug, not fixed in this patch."
+ );
+
+ Composite composite = new Composite (shell, 0);
+ composite.setLayoutData (new GridData (SWT.FILL, SWT.FILL, true, true));
+ composite.setLayout (new GridLayout (4, true));
+
+ new Label(composite, 0).setText ("Table");
+ new Label(composite, 0).setText ("Table+Images");
+ new Label(composite, 0).setText ("Table+PaintItem");
+ new Label(composite, 0).setText ("Table+PaintItem+Images");
+ createTable(composite, false, false);
+ createTable(composite, false, true);
+ createTable(composite, true, false);
+ createTable(composite, true, true);
+
+ new Label(composite, 0).setText ("Tree");
+ new Label(composite, 0).setText ("Tree+Images");
+ new Label(composite, 0).setText ("Tree+PaintItem");
+ new Label(composite, 0).setText ("Tree+PaintItem+Images");
+ createTree(composite, false, false);
+ createTree(composite, false, true);
+ createTree(composite, true, false);
+ createTree(composite, true, true);
+
+ shell.setSize (900, 600);
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ display.dispose();
+ }
+}
diff --git a/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug578171_macOS_JvmCrash_ShowMenuWindow.java b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug578171_macOS_JvmCrash_ShowMenuWindow.java
new file mode 100644
index 0000000000..2fd8c97bae
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug578171_macOS_JvmCrash_ShowMenuWindow.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Syntevo and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Syntevo - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.swt.tests.manual;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public class Bug578171_macOS_JvmCrash_ShowMenuWindow {
+ public static void main(String[] args) {
+ final Display display = new Display();
+ final Shell shell = new Shell(display);
+ shell.setLayout(new GridLayout(1, true));
+
+ new Label(shell, 0).setText(
+ "1) Use macOS 12 (macOS < 12 are not affected)\n" +
+ "2) Press the button\n" +
+ "3) Click menu bar and move mouse left-right to switch between submenus\n" +
+ "4) Bug 578171: Popup Shell will be activated; that's a bug already\n" +
+ "5) Bug 578171: JVM will crash"
+ );
+
+ Menu rootMenu = new Menu(shell, SWT.BAR);
+ shell.setMenuBar(rootMenu);
+ for (int iMenu = 0; iMenu < 3; iMenu++) {
+ MenuItem rootItem = new MenuItem(rootMenu, SWT.CASCADE);
+ rootItem.setText("Menu:" + iMenu);
+
+ Menu menu = new Menu(shell, SWT.DROP_DOWN);
+ rootItem.setMenu(menu);
+
+ for (int iItem = 0; iItem < 10; iItem++) {
+ MenuItem item = new MenuItem(menu, SWT.CASCADE);
+ item.setText("MenuItem:" + iMenu + ":" + iItem);
+ }
+ }
+
+ Button button = new Button(shell, SWT.PUSH);
+ button.setText("Show popup after 2000ms");
+ button.addListener(SWT.Selection, e -> {
+ display.timerExec(2000, () -> {
+ Shell popup = new Shell(shell, SWT.DIALOG_TRIM);
+ popup.addListener(SWT.Activate, e2 -> {
+ System.out.println("Popup Shell SWT.Activate: It's a bug when it happens without clicking the popup");
+ });
+
+ popup.setSize(100, 100);
+ popup.setVisible(true);
+ });
+ });
+
+ new Label(shell, 0).setText("A text field so that you can check if Shell is still active:");
+ new Text(shell, 0).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ shell.pack();
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ display.dispose();
+ }
+} \ No newline at end of file
diff --git a/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/SnippetDrawAlpha.java b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/SnippetDrawAlpha.java
new file mode 100644
index 0000000000..2570ba506e
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/SnippetDrawAlpha.java
@@ -0,0 +1,98 @@
+package org.eclipse.swt.tests.manual;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+public class SnippetDrawAlpha {
+ public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setLayout(new GridLayout(4, false));
+
+ createImageLabels(display, shell, "/eclipse16.png");
+ createImageLabels(display, shell, "/eclipse32.png");
+ createImageLabels(display, shell, "/pause.gif");
+ createImageLabels(display, shell, "/run.gif");
+ createImageLabels(display, shell, "/warning.gif");
+ createImageLabels(display, shell, "/transparent.png");
+
+ shell.pack();
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+ }
+
+ private static void createImageLabels(Display display, Shell shell, String fileName) {
+ createImageLabel(display, shell, fileName, -1);
+ createImageLabel(display, shell, fileName, 1);
+ createImageLabel(display, shell, fileName, 1.5f);
+ createImageLabel(display, shell, fileName, 2);
+ }
+
+ private static void createImageLabel(Display display, Shell shell, String fileName, float scaleFactor) {
+ ImageLoader loader = new ImageLoader();
+ loader.load(SnippetDrawAlpha.class.getResourceAsStream(fileName));
+ ImageData data = loader.data[0];
+ if (scaleFactor != -1) {
+ data = autoScaleImageData(display, data, scaleFactor);
+ }
+ Image image = new Image(display, data);
+ Label label = new Label(shell, SWT.NONE);
+ label.setImage(image);
+ }
+
+ private static ImageData autoScaleImageData(Device device, final ImageData imageData, float scaleFactor) {
+ int width = imageData.width;
+ int height = imageData.height;
+ int scaledWidth = Math.round(width * scaleFactor);
+ int scaledHeight = Math.round(height * scaleFactor);
+
+ Image original = new Image(device, imageData);
+
+ /* Create a 24 bit image data with alpha channel */
+ final ImageData resultData = new ImageData(scaledWidth, scaledHeight, 24,
+ new PaletteData(0xFF, 0xFF00, 0xFF0000));
+ resultData.alphaData = new byte[scaledWidth * scaledHeight];
+
+ /*
+ * FIXME: something is wrong in SWT on win32. alphaData is apparently
+ * not used in GC#drawImage(..) below, and images end up fully
+ * transparent.
+ */
+// if ("win32".equals(SWT.getPlatform())) {
+// // This hack makes the images at least visible, but loses all transparency:
+// Arrays.fill (resultData.alphaData, (byte) 0xFF);
+// // Makes the wrong non-transparent background white instead of black:
+// Arrays.fill(resultData.data, (byte) 0xFF);
+// }
+
+ Image resultImage = new Image(device, resultData);
+ GC gc = new GC(resultImage);
+ gc.setAntialias(SWT.ON);
+ gc.drawImage(original, 0, 0, width, height,
+ /*
+ * E.g. destWidth here is effectively DPIUtil.autoScaleDown
+ * (scaledWidth), but avoiding rounding errors. Nevertheless, we
+ * still have some rounding errors due to the point-based API
+ * GC#drawImage(..).
+ */
+ 0, 0, scaledWidth, scaledHeight);
+ gc.dispose();
+ original.dispose();
+ ImageData result = resultImage.getImageData();
+ resultImage.dispose();
+ return result;
+ }
+} \ No newline at end of file
diff --git a/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/SnippetDrawAlphaTwoPass.java b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/SnippetDrawAlphaTwoPass.java
new file mode 100644
index 0000000000..9e21d134d4
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/SnippetDrawAlphaTwoPass.java
@@ -0,0 +1,159 @@
+package org.eclipse.swt.tests.manual;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Device;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+public class SnippetDrawAlphaTwoPass {
+
+ // Alpha and BW palette definitions from org.eclipse.ui.internal.decorators.DecorationImageBuilder
+ private static final PaletteData ALPHA_PALETTE, BW_PALETTE;
+
+ static {
+ RGB[] rgbs = new RGB[256];
+ for (int i = 0; i < rgbs.length; i++) {
+ rgbs[i] = new RGB(i, i, i);
+ }
+
+ ALPHA_PALETTE = new PaletteData(rgbs);
+ BW_PALETTE = new PaletteData(new RGB[] { new RGB(0, 0, 0), new RGB(255, 255, 255) });
+ }
+
+ public static void main(String[] args) {
+ Display display = new Display();
+ Shell shell = new Shell(display);
+ shell.setLayout(new GridLayout(4, false));
+
+ createImageLabels(display, shell, "/eclipse16.png");
+ createImageLabels(display, shell, "/eclipse32.png");
+ createImageLabels(display, shell, "/pause.gif");
+ createImageLabels(display, shell, "/run.gif");
+ createImageLabels(display, shell, "/warning.gif");
+ createImageLabels(display, shell, "/transparent.png");
+
+ shell.pack();
+ shell.open();
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch())
+ display.sleep();
+ }
+ display.dispose();
+ }
+
+ private static void createImageLabels(Display display, Shell shell, String fileName) {
+ createImageLabel(display, shell, fileName, -1);
+ createImageLabel(display, shell, fileName, 1);
+ createImageLabel(display, shell, fileName, 1.5f);
+ createImageLabel(display, shell, fileName, 2);
+ }
+
+ private static void createImageLabel(Display display, Shell shell, String fileName, float scaleFactor) {
+ ImageLoader loader = new ImageLoader();
+ loader.load(SnippetDrawAlpha.class.getResourceAsStream(fileName));
+ ImageData data = loader.data[0];
+ if (scaleFactor != -1) {
+ data = autoScaleImageData(display, data, scaleFactor);
+ }
+ Image image = new Image(display, data);
+ Label label = new Label(shell, SWT.NONE);
+ label.setImage(image);
+ }
+
+ private static ImageData autoScaleImageData(Device device, final ImageData imageData, float scaleFactor) {
+ int width = imageData.width;
+ int height = imageData.height;
+ int scaledWidth = Math.round(width * scaleFactor);
+ int scaledHeight = Math.round(height * scaleFactor);
+
+ ImageData imageMaskData = null;
+
+ if (imageData.getTransparencyType() == SWT.TRANSPARENCY_ALPHA) {
+ imageMaskData = new ImageData(width, height, 8, ALPHA_PALETTE, 1, imageData.alphaData);
+ } else if (imageData.getTransparencyType() == SWT.TRANSPARENCY_PIXEL || imageData.getTransparencyType() == SWT.TRANSPARENCY_MASK) {
+ ImageData transparencyMaskData = imageData.getTransparencyMask();
+ imageMaskData = new ImageData(width, height, 1, BW_PALETTE, transparencyMaskData.scanlinePad, transparencyMaskData.data);
+ }
+
+ Image original = new Image(device, imageData);
+ Image originalMask = null;
+
+ if (imageMaskData != null) {
+ originalMask = new Image(device, imageMaskData);
+ }
+
+ /* Create a 24 bit image data with alpha channel */
+ ImageData resultData = new ImageData(scaledWidth, scaledHeight, 24, new PaletteData(0xFF, 0xFF00, 0xFF0000));
+ ImageData resultMaskData = null;
+
+ if (imageMaskData != null) {
+ resultMaskData = new ImageData(scaledWidth, scaledHeight, imageMaskData.depth, imageMaskData.palette);
+ }
+
+ Image result = new Image(device, resultData);
+ Image resultMask = null;
+
+ GC gc = new GC(result);
+ gc.setAntialias(SWT.ON);
+ gc.drawImage(original, 0, 0, width, height, 0, 0, scaledWidth, scaledHeight);
+ gc.dispose();
+
+ if (resultMaskData != null) {
+ resultMask = new Image(device, resultMaskData);
+ gc = new GC(resultMask);
+ gc.setAntialias(SWT.ON);
+ gc.drawImage(originalMask, 0, 0, width, height, 0, 0, scaledWidth, scaledHeight);
+ gc.dispose();
+ }
+
+ original.dispose();
+ originalMask.dispose();
+
+ ImageData scaledResult = result.getImageData();
+
+ if (resultMask != null) {
+ ImageData scaledResultMaskData = resultMask.getImageData();
+
+ // Convert 1-bit mask
+ if (scaledResultMaskData.depth == 1) {
+ scaledResult.maskPad = scaledResultMaskData.scanlinePad;
+ scaledResult.maskData = scaledResultMaskData.data;
+ } else {
+ byte[] alphaData = scaledResultMaskData.data;
+ if (scaledResultMaskData.scanlinePad != 1) {
+ alphaData = convertPad(scaledResultMaskData.data, scaledResultMaskData.width, scaledResultMaskData.height,
+ scaledResultMaskData.depth, scaledResultMaskData.scanlinePad, 1);
+ }
+ scaledResult.alphaData = alphaData;
+ }
+ }
+
+ result.dispose();
+ resultMask.dispose();
+ return scaledResult;
+ }
+
+ // copied from ImageData.convertPad as it is not accessible outside the org.eclipse.swt package
+ private static byte[] convertPad(byte[] data, int width, int height, int depth, int pad, int newPad) {
+ if (pad == newPad) return data;
+ int stride = (width * depth + 7) / 8;
+ int bpl = (stride + (pad - 1)) / pad * pad;
+ int newBpl = (stride + (newPad - 1)) / newPad * newPad;
+ byte[] newData = new byte[height * newBpl];
+ int srcIndex = 0, destIndex = 0;
+ for (int y = 0; y < height; y++) {
+ System.arraycopy(data, srcIndex, newData, destIndex, stride);
+ srcIndex += bpl;
+ destIndex += newBpl;
+ }
+ return newData;
+ }
+} \ No newline at end of file
diff --git a/tests/org.eclipse.swt.tests/data/eclipse.png b/tests/org.eclipse.swt.tests/data/eclipse.png
new file mode 100644
index 0000000000..73975241eb
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/data/eclipse.png
Binary files differ
diff --git a/tests/org.eclipse.swt.tests/data/eclipse16.png b/tests/org.eclipse.swt.tests/data/eclipse16.png
new file mode 100644
index 0000000000..7fc69518a8
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/data/eclipse16.png
Binary files differ
diff --git a/tests/org.eclipse.swt.tests/data/eclipse24.png b/tests/org.eclipse.swt.tests/data/eclipse24.png
new file mode 100644
index 0000000000..fbddd3cd78
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/data/eclipse24.png
Binary files differ
diff --git a/tests/org.eclipse.swt.tests/data/eclipse32.png b/tests/org.eclipse.swt.tests/data/eclipse32.png
new file mode 100644
index 0000000000..bf85680075
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/data/eclipse32.png
Binary files differ
diff --git a/tests/org.eclipse.swt.tests/data/pause.gif b/tests/org.eclipse.swt.tests/data/pause.gif
new file mode 100644
index 0000000000..161e3f594f
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/data/pause.gif
Binary files differ
diff --git a/tests/org.eclipse.swt.tests/data/run.gif b/tests/org.eclipse.swt.tests/data/run.gif
new file mode 100644
index 0000000000..944a230aad
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/data/run.gif
Binary files differ
diff --git a/tests/org.eclipse.swt.tests/data/warning.gif b/tests/org.eclipse.swt.tests/data/warning.gif
new file mode 100644
index 0000000000..cf4fdf93c7
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/data/warning.gif
Binary files differ
diff --git a/tests/org.eclipse.swt.tests/pom.xml b/tests/org.eclipse.swt.tests/pom.xml
index 264d236f70..997f93499a 100644
--- a/tests/org.eclipse.swt.tests/pom.xml
+++ b/tests/org.eclipse.swt.tests/pom.xml
@@ -14,12 +14,12 @@
<parent>
<artifactId>eclipse.platform.swt.localbuild</artifactId>
<groupId>eclipse.platform.swt</groupId>
- <version>4.23.0-SNAPSHOT</version>
+ <version>4.24.0-SNAPSHOT</version>
<relativePath>../../local-build/local-build-parent/</relativePath>
</parent>
<groupId>org.eclipse.swt</groupId>
<artifactId>org.eclipse.swt.tests</artifactId>
- <version>3.106.1600-SNAPSHOT</version>
+ <version>3.106.1700-SNAPSHOT</version>
<packaging>eclipse-test-plugin</packaging>
<properties>
<code.ignoredWarnings>${tests.ignoredWarnings}</code.ignoredWarnings>

Back to the top