|
25 | 25 | import java.util.function.*; |
26 | 26 |
|
27 | 27 | import org.eclipse.swt.*; |
| 28 | +import org.eclipse.swt.events.*; |
28 | 29 | import org.eclipse.swt.graphics.*; |
29 | 30 | import org.eclipse.swt.internal.*; |
30 | 31 | import org.eclipse.swt.internal.gtk.*; |
@@ -96,7 +97,11 @@ class WebKit extends WebBrowser { |
96 | 97 | URI tlsErrorUri; |
97 | 98 | String tlsErrorType; |
98 | 99 |
|
| 100 | + private Shell searchShell; |
| 101 | + private String searchText; |
| 102 | + |
99 | 103 | boolean firstLoad = true; |
| 104 | + |
100 | 105 | static boolean FirstCreate = true; |
101 | 106 |
|
102 | 107 | /** |
@@ -784,13 +789,25 @@ public void create (Composite parent, int style) { |
784 | 789 | onResize (event); |
785 | 790 | break; |
786 | 791 | } |
| 792 | + case SWT.KeyDown: { |
| 793 | + if (event.keyCode == 'f' && (event.stateMask & SWT.CTRL) == SWT.CTRL) { |
| 794 | + openSearchDialog(); |
| 795 | + } |
| 796 | + break; |
| 797 | + } |
787 | 798 | } |
788 | 799 | }; |
789 | 800 | browser.addListener (SWT.Dispose, listener); |
790 | 801 | browser.addListener (SWT.FocusIn, listener); |
791 | 802 | browser.addListener (SWT.KeyDown, listener); |
792 | 803 | browser.addListener (SWT.Resize, listener); |
793 | 804 |
|
| 805 | + browser.addDisposeListener(e -> { |
| 806 | + if (searchShell != null && !searchShell.isDisposed()) { |
| 807 | + searchShell.close(); |
| 808 | + } |
| 809 | + }); |
| 810 | + |
794 | 811 | /* |
795 | 812 | * Bug in WebKitGTK. MouseOver/MouseLeave events are not consistently sent from |
796 | 813 | * 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) { |
2665 | 2682 | OS.g_object_set(settings, property, value, 0); |
2666 | 2683 | } |
2667 | 2684 |
|
| 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 | + |
2668 | 2740 | static Object convertToJava (long ctx, long value) { |
2669 | 2741 | int type = WebKitGTK.JSValueGetType (ctx, value); |
2670 | 2742 | switch (type) { |
|
0 commit comments