Skip to content

Commit 4c30cc6

Browse files
committed
[WIP] 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 4c30cc6

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

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

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

100+
private Shell searchShell;
101+
private String searchText;
102+
99103
boolean firstLoad = true;
104+
100105
static boolean FirstCreate = true;
101106

102107
/**
@@ -784,13 +789,25 @@ 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+
if (searchShell != null && !searchShell.isDisposed()) {
807+
searchShell.close();
808+
}
809+
});
810+
794811
/*
795812
* Bug in WebKitGTK. MouseOver/MouseLeave events are not consistently sent from
796813
* the DOM when the mouse enters and exits the browser control, see
@@ -2665,6 +2682,61 @@ private void webkit_settings_set(byte [] property, int value) {
26652682
OS.g_object_set(settings, property, value, 0);
26662683
}
26672684

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