Skip to content

Commit 1722c3e

Browse files
committed
Add search capabilities to WebKit based Browser
This changes adds a search dialog to WebKit browsers. The search dialog is opened with Ctrl+F and has next/previous word matching capabilities. Fixes: #2222
1 parent 0a68dea commit 1722c3e

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.function.*;
2626

2727
import org.eclipse.swt.*;
28+
import org.eclipse.swt.events.*;
2829
import org.eclipse.swt.graphics.*;
2930
import org.eclipse.swt.internal.*;
3031
import org.eclipse.swt.internal.gtk.*;
@@ -96,6 +97,10 @@ class WebKit extends WebBrowser {
9697
URI tlsErrorUri;
9798
String tlsErrorType;
9899

100+
private final ControlListener shellMoveListener = ControlListener.controlMovedAdapter(e -> closeSearchDialog());
101+
private Shell searchShell;
102+
private String searchText;
103+
99104
boolean firstLoad = true;
100105
static boolean FirstCreate = true;
101106

@@ -784,13 +789,26 @@ public void create (Composite parent, int style) {
784789
onResize (event);
785790
break;
786791
}
792+
case SWT.KeyDown: {
793+
if (event.keyCode == 'f' && (event.stateMask & SWT.CTRL) == SWT.CTRL) {
794+
openSearchDialog();
795+
}
796+
break;
797+
}
787798
}
788799
};
789800
browser.addListener (SWT.Dispose, listener);
790801
browser.addListener (SWT.FocusIn, listener);
791802
browser.addListener (SWT.KeyDown, listener);
792803
browser.addListener (SWT.Resize, listener);
793804

805+
browser.addDisposeListener(e -> {
806+
closeSearchDialog();
807+
});
808+
browser.addControlListener(ControlListener.controlResizedAdapter(e -> closeSearchDialog()));
809+
browser.addControlListener(ControlListener.controlMovedAdapter(e -> closeSearchDialog()));
810+
browser.getShell().addControlListener(shellMoveListener);
811+
794812
/*
795813
* Bug in WebKitGTK. MouseOver/MouseLeave events are not consistently sent from
796814
* the DOM when the mouse enters and exits the browser control, see
@@ -835,6 +853,9 @@ public boolean close () {
835853
// false = blocks disposal. In Browser.java, user is told widget was not disposed.
836854
// See Snippet326.
837855
boolean close (boolean showPrompters) {
856+
if (browser != null && !browser.isDisposed()) {
857+
browser.getShell().removeControlListener(shellMoveListener);
858+
}
838859
// don't execute any JavaScript if it's disabled or requested to get disabled
839860
// we need to check jsEnabledOnNextPage here because jsEnabled is updated asynchronously
840861
// and may not reflect the proper state (bug 571746 and bug 567881)
@@ -2665,6 +2686,71 @@ private void webkit_settings_set(byte [] property, int value) {
26652686
OS.g_object_set(settings, property, value, 0);
26662687
}
26672688

2689+
private void closeSearchDialog() {
2690+
if (searchShell != null && !searchShell.isDisposed()) {
2691+
searchShell.close();
2692+
if (searchText != null && webView != 0) {
2693+
long findController = WebKitGTK.webkit_web_view_get_find_controller(webView);
2694+
WebKitGTK.webkit_find_controller_search_finish(findController);
2695+
}
2696+
searchText = null;
2697+
}
2698+
}
2699+
2700+
private void openSearchDialog() {
2701+
if (webView == 0 || (searchShell != null && !searchShell.isDisposed())) {
2702+
return;
2703+
}
2704+
Shell shell = new Shell(browser.getShell(), SWT.TOOL | SWT.MODELESS);
2705+
shell.setLayout(new FillLayout());
2706+
Point browserLocation = browser.getLocation();
2707+
Rectangle browserArea = browser.getClientArea();
2708+
Point location = browser.getShell().getLocation();
2709+
location.x += browserLocation.x;
2710+
location.y += browserLocation.y + Math.max(0, browserArea.height - 20);
2711+
shell.setBounds(location.x, location.y, 250, 40);
2712+
GridLayout l = new GridLayout();
2713+
l.numColumns = 3;
2714+
shell.setLayout(l);
2715+
Text text = new Text(shell, SWT.BORDER);
2716+
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
2717+
Button next = new Button(shell, SWT.FLAT | SWT.ARROW | SWT.DOWN);
2718+
Button previous = new Button(shell, SWT.FLAT | SWT.ARROW | SWT.UP);
2719+
2720+
long findController = WebKitGTK.webkit_web_view_get_find_controller(webView);
2721+
Runnable searchNext = () -> search(findController, text::getText, WebKitGTK::webkit_find_controller_search_next);
2722+
Runnable searchPrevious = () -> search(findController, text::getText, WebKitGTK::webkit_find_controller_search_previous);
2723+
next.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> searchNext.run()));
2724+
previous.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> searchPrevious.run()));
2725+
text.addKeyListener(KeyListener.keyPressedAdapter(e -> {
2726+
if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
2727+
searchNext.run();
2728+
}
2729+
}));
2730+
shell.addDisposeListener(e -> {
2731+
WebKitGTK.webkit_find_controller_search_finish(findController);
2732+
searchShell = null;
2733+
});
2734+
shell.open();
2735+
searchShell = shell;
2736+
}
2737+
2738+
private void search(long findController, Supplier<String> currentText, Consumer<Long> incrementSearch) {
2739+
int maxMatchesCount = WebKitGTK.G_MAXUINT; // TODO: how to set no max count here?
2740+
int searchOptions = WebKitGTK.WEBKIT_FIND_OPTIONS_WRAP_AROUND;
2741+
String text = currentText.get();
2742+
if (!text.equals(searchText)) {
2743+
if (searchText != null) {
2744+
WebKitGTK.webkit_find_controller_search_finish(findController);
2745+
}
2746+
searchText = text;
2747+
byte[] textToSearch = Converter.wcsToMbcs(searchText, true);
2748+
WebKitGTK.webkit_find_controller_search(findController, textToSearch, searchOptions, maxMatchesCount);
2749+
} else {
2750+
incrementSearch.accept(Long.valueOf(findController));
2751+
}
2752+
}
2753+
26682754
static Object convertToJava (long ctx, long value) {
26692755
int type = WebKitGTK.JSValueGetType (ctx, value);
26702756
switch (type) {

bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ public class WebKitGTK extends C {
9090
public static final int WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START = 0;
9191
public static final int WEBKIT_USER_CONTENT_INJECT_TOP_FRAME = 1;
9292

93+
public static final int G_MAXUINT = 65535;
94+
public static final int WEBKIT_FIND_OPTIONS_WRAP_AROUND = 1 << 4;
95+
9396
/** Signals */
9497

9598
// Authentication.

0 commit comments

Comments
 (0)