Skip to content

Commit 52607ae

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 52607ae

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

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

Lines changed: 85 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,9 @@ class WebKit extends WebBrowser {
9697
URI tlsErrorUri;
9798
String tlsErrorType;
9899

100+
private Shell searchShell;
101+
private String searchText;
102+
99103
boolean firstLoad = true;
100104
static boolean FirstCreate = true;
101105

@@ -784,13 +788,33 @@ public void create (Composite parent, int style) {
784788
onResize (event);
785789
break;
786790
}
791+
case SWT.KeyDown: {
792+
if (event.keyCode == 'f' && (event.stateMask & SWT.CTRL) == SWT.CTRL) {
793+
openSearchDialog();
794+
}
795+
break;
796+
}
787797
}
788798
};
789799
browser.addListener (SWT.Dispose, listener);
790800
browser.addListener (SWT.FocusIn, listener);
791801
browser.addListener (SWT.KeyDown, listener);
792802
browser.addListener (SWT.Resize, listener);
793803

804+
browser.addDisposeListener(e -> {
805+
closeSearchDialog();
806+
});
807+
browser.addControlListener(new ControlListener() {
808+
@Override
809+
public void controlResized(ControlEvent e) {
810+
closeSearchDialog();
811+
}
812+
@Override
813+
public void controlMoved(ControlEvent e) {
814+
closeSearchDialog();
815+
}
816+
});
817+
794818
/*
795819
* Bug in WebKitGTK. MouseOver/MouseLeave events are not consistently sent from
796820
* the DOM when the mouse enters and exits the browser control, see
@@ -2665,6 +2689,67 @@ private void webkit_settings_set(byte [] property, int value) {
26652689
OS.g_object_set(settings, property, value, 0);
26662690
}
26672691

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