Title: [248033] trunk
Revision
248033
Author
[email protected]
Date
2019-07-31 01:02:09 -0700 (Wed, 31 Jul 2019)

Log Message

[GTK] Datalist element support for TextFieldInputType
https://bugs.webkit.org/show_bug.cgi?id=98934

Reviewed by Michael Catanzaro.

.:

Enable DATALIST_ELEMENT.

* Source/cmake/OptionsGTK.cmake:

Source/WebCore:

Add support for rendering the arrow indicator of text fields having data list.

* rendering/RenderThemeGtk.cpp:
(WebCore::RenderThemeGtk::paintTextField):
(WebCore::RenderThemeGtk::adjustListButtonStyle const):
(WebCore::RenderThemeGtk::paintListButtonForInput):
(WebCore::RenderThemeGtk::adjustSearchFieldStyle const):
* rendering/RenderThemeGtk.h:

Source/WebKit:

Add a WebDataListSuggestionsDropdown implementation for the GTK port using a popup window with a tree view list.

* Sources.txt:
* SourcesGTK.txt:
* UIProcess/API/gtk/PageClientImpl.cpp:
(WebKit::PageClientImpl::createDataListSuggestionsDropdown):
* UIProcess/API/gtk/PageClientImpl.h:
* UIProcess/gtk/WebDataListSuggestionsDropdownGtk.cpp: Added.
(WebKit::firstTimeItemSelectedCallback):
(WebKit::WebDataListSuggestionsDropdownGtk::WebDataListSuggestionsDropdownGtk):
(WebKit::WebDataListSuggestionsDropdownGtk::~WebDataListSuggestionsDropdownGtk):
(WebKit::WebDataListSuggestionsDropdownGtk::treeViewRowActivatedCallback):
(WebKit::WebDataListSuggestionsDropdownGtk::didSelectOption):
(WebKit::WebDataListSuggestionsDropdownGtk::show):
(WebKit::WebDataListSuggestionsDropdownGtk::handleKeydownWithIdentifier):
(WebKit::WebDataListSuggestionsDropdownGtk::close):
* UIProcess/gtk/WebDataListSuggestionsDropdownGtk.h: Copied from Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h.

Tools:

Implement UIScriptControllerGtk::isShowingDataListSuggestions.

* WebKitTestRunner/gtk/UIScriptControllerGtk.cpp:
(WTR::UIScriptControllerGtk::isShowingDataListSuggestions const):
* WebKitTestRunner/gtk/UIScriptControllerGtk.h:

LayoutTests:

Unskip datalist tests for GTK port.

* platform/gtk/TestExpectations:

Modified Paths

Added Paths

Diff

Modified: trunk/ChangeLog (248032 => 248033)


--- trunk/ChangeLog	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/ChangeLog	2019-07-31 08:02:09 UTC (rev 248033)
@@ -1,3 +1,14 @@
+2019-07-31  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Datalist element support for TextFieldInputType
+        https://bugs.webkit.org/show_bug.cgi?id=98934
+
+        Reviewed by Michael Catanzaro.
+
+        Enable DATALIST_ELEMENT.
+
+        * Source/cmake/OptionsGTK.cmake:
+
 2019-07-24  Fujii Hironori  <[email protected]>
 
         [CMake] CMAKE_SHARED_LINKER_FLAGS drops "-Wl,--no-undefined"

Modified: trunk/LayoutTests/ChangeLog (248032 => 248033)


--- trunk/LayoutTests/ChangeLog	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/LayoutTests/ChangeLog	2019-07-31 08:02:09 UTC (rev 248033)
@@ -1,3 +1,14 @@
+2019-07-31  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Datalist element support for TextFieldInputType
+        https://bugs.webkit.org/show_bug.cgi?id=98934
+
+        Reviewed by Michael Catanzaro.
+
+        Unskip datalist tests for GTK port.
+
+        * platform/gtk/TestExpectations:
+
 2019-07-31  Zan Dobersek  <[email protected]>
 
         Unreviewed WPE gardening.

Modified: trunk/LayoutTests/platform/gtk/TestExpectations (248032 => 248033)


--- trunk/LayoutTests/platform/gtk/TestExpectations	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/LayoutTests/platform/gtk/TestExpectations	2019-07-31 08:02:09 UTC (rev 248033)
@@ -177,10 +177,6 @@
 fast/history/page-cache-notification-non-suspendable.html
 fast/history/page-cache-notification-suspendable.html
 
-# Datalist is not yet enabled.
-accessibility/datalist.html [ Skip ]
-webkit.org/b/98934 fast/forms/datalist [ Skip ]
-
 # ENABLE_INPUT_TYPE_* are not enabled.
 webkit.org/b/98936 fast/forms/date [ Skip ]
 webkit.org/b/98936 fast/forms/datetime [ Skip ]
@@ -3799,6 +3795,7 @@
 webkit.org/b/199859 imported/w3c/web-platform-tests/css/css-text/line-break/line-break-anywhere-001.html [ ImageOnlyFailure ]
 
 webkit.org/b/199860 accessibility/button-with-aria-haspopup-role.html [ Failure ]
+webkit.org/b/199860 accessibility/datalist.html [ Failure ]
 webkit.org/b/199868 accessibility/gtk/aria-haspopup.html [ Failure ]
 
 webkit.org/b/199440 fast/mediastream/apply-constraints-video.html [ Failure ]

Modified: trunk/Source/WebCore/ChangeLog (248032 => 248033)


--- trunk/Source/WebCore/ChangeLog	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Source/WebCore/ChangeLog	2019-07-31 08:02:09 UTC (rev 248033)
@@ -1,3 +1,19 @@
+2019-07-31  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Datalist element support for TextFieldInputType
+        https://bugs.webkit.org/show_bug.cgi?id=98934
+
+        Reviewed by Michael Catanzaro.
+
+        Add support for rendering the arrow indicator of text fields having data list.
+
+        * rendering/RenderThemeGtk.cpp:
+        (WebCore::RenderThemeGtk::paintTextField):
+        (WebCore::RenderThemeGtk::adjustListButtonStyle const):
+        (WebCore::RenderThemeGtk::paintListButtonForInput):
+        (WebCore::RenderThemeGtk::adjustSearchFieldStyle const):
+        * rendering/RenderThemeGtk.h:
+
 2019-07-30  Tim Horton  <[email protected]>
 
         ASSERTion failure under takeSnapshot after r247846

Modified: trunk/Source/WebCore/rendering/RenderThemeGtk.cpp (248032 => 248033)


--- trunk/Source/WebCore/rendering/RenderThemeGtk.cpp	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Source/WebCore/rendering/RenderThemeGtk.cpp	2019-07-31 08:02:09 UTC (rev 248033)
@@ -520,6 +520,14 @@
         auto& entryWidget = static_cast<RenderThemeEntry&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::Entry));
         entryWidget.entry().setState(themePartStateFlags(*this, Entry, renderObject));
         entryWidget.entry().render(paintInfo.context().platformContext()->cr(), rect);
+
+#if ENABLE(DATALIST_ELEMENT)
+        if (is<HTMLInputElement>(renderObject.generatingNode())) {
+            const auto& input = downcast<HTMLInputElement>(*(renderObject.generatingNode()));
+            if (input.list())
+                paintListButtonForInput(renderObject, paintInfo, rect);
+        }
+#endif
     }
     return false;
 }
@@ -597,6 +605,34 @@
     return paintSearchFieldIcon(this, EntryIconRight, renderObject, paintInfo, rect);
 }
 
+#if ENABLE(DATALIST_ELEMENT)
+void RenderThemeGtk::adjustListButtonStyle(StyleResolver&, RenderStyle& style, const Element*) const
+{
+    // Add a margin to place the button at end of the input field.
+    if (style.isLeftToRightDirection())
+        style.setMarginRight(Length(-4, Fixed));
+    else
+        style.setMarginLeft(Length(-4, Fixed));
+}
+
+void RenderThemeGtk::paintListButtonForInput(const RenderObject& renderObject, const PaintInfo& paintInfo, const FloatRect& rect)
+{
+    // Use a combo box widget to render its arrow.
+    auto& comboWidget = static_cast<RenderThemeComboBox&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::ComboBox));
+    comboWidget.arrow().setState(themePartStateFlags(*this, ComboBoxButton, renderObject));
+
+    // But a search entry widget to get the contents rect, since this is a text input field.
+    auto& searchEntryWidget = static_cast<RenderThemeSearchEntry&>(RenderThemeWidget::getOrCreate(RenderThemeWidget::Type::SearchEntry));
+    auto& icon = static_cast<RenderThemeIconGadget&>(searchEntryWidget.rightIcon());
+    icon.setIconSize(comboWidget.arrow().preferredSize().width());
+    GtkBorder contentsBox = searchEntryWidget.entry().contentsBox();
+    FloatRect adjustedRect(rect);
+    adjustedRect.move(contentsBox.left, contentsBox.top);
+    adjustedRect.contract(contentsBox.right + 1, contentsBox.top + contentsBox.bottom);
+    comboWidget.arrow().render(paintInfo.context().platformContext()->cr(), adjustedRect);
+}
+#endif
+
 void RenderThemeGtk::adjustSearchFieldStyle(StyleResolver&, RenderStyle& style, const Element*) const
 {
     // We cannot give a proper rendering when border radius is active, unfortunately.

Modified: trunk/Source/WebCore/rendering/RenderThemeGtk.h (248032 => 248033)


--- trunk/Source/WebCore/rendering/RenderThemeGtk.h	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Source/WebCore/rendering/RenderThemeGtk.h	2019-07-31 08:02:09 UTC (rev 248033)
@@ -143,6 +143,11 @@
     void adjustSearchFieldCancelButtonStyle(StyleResolver&, RenderStyle&, const Element*) const override;
     bool paintSearchFieldCancelButton(const RenderBox&, const PaintInfo&, const IntRect&) override;
 
+#if ENABLE(DATALIST_ELEMENT)
+    void paintListButtonForInput(const RenderObject&, const PaintInfo&, const FloatRect&);
+    void adjustListButtonStyle(StyleResolver&, RenderStyle&, const Element*) const override;
+#endif
+
     bool paintSliderTrack(const RenderObject&, const PaintInfo&, const IntRect&) override;
     void adjustSliderTrackStyle(StyleResolver&, RenderStyle&, const Element*) const override;
 

Modified: trunk/Source/WebKit/ChangeLog (248032 => 248033)


--- trunk/Source/WebKit/ChangeLog	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Source/WebKit/ChangeLog	2019-07-31 08:02:09 UTC (rev 248033)
@@ -1,3 +1,28 @@
+2019-07-31  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Datalist element support for TextFieldInputType
+        https://bugs.webkit.org/show_bug.cgi?id=98934
+
+        Reviewed by Michael Catanzaro.
+
+        Add a WebDataListSuggestionsDropdown implementation for the GTK port using a popup window with a tree view list.
+
+        * Sources.txt:
+        * SourcesGTK.txt:
+        * UIProcess/API/gtk/PageClientImpl.cpp:
+        (WebKit::PageClientImpl::createDataListSuggestionsDropdown):
+        * UIProcess/API/gtk/PageClientImpl.h:
+        * UIProcess/gtk/WebDataListSuggestionsDropdownGtk.cpp: Added.
+        (WebKit::firstTimeItemSelectedCallback):
+        (WebKit::WebDataListSuggestionsDropdownGtk::WebDataListSuggestionsDropdownGtk):
+        (WebKit::WebDataListSuggestionsDropdownGtk::~WebDataListSuggestionsDropdownGtk):
+        (WebKit::WebDataListSuggestionsDropdownGtk::treeViewRowActivatedCallback):
+        (WebKit::WebDataListSuggestionsDropdownGtk::didSelectOption):
+        (WebKit::WebDataListSuggestionsDropdownGtk::show):
+        (WebKit::WebDataListSuggestionsDropdownGtk::handleKeydownWithIdentifier):
+        (WebKit::WebDataListSuggestionsDropdownGtk::close):
+        * UIProcess/gtk/WebDataListSuggestionsDropdownGtk.h: Copied from Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h.
+
 2019-07-31  Tim Horton  <[email protected]>
 
         Remove WebKit2 Makefile guards for pre-Snow Leopard macOS

Modified: trunk/Source/WebKit/Sources.txt (248032 => 248033)


--- trunk/Source/WebKit/Sources.txt	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Source/WebKit/Sources.txt	2019-07-31 08:02:09 UTC (rev 248033)
@@ -268,6 +268,7 @@
 UIProcess/WebContextMenuProxy.cpp
 UIProcess/WebCookieManagerProxy.cpp
 UIProcess/WebCookieManagerProxyClient.cpp
+UIProcess/WebDataListSuggestionsDropdown.cpp
 UIProcess/WebEditCommandProxy.cpp
 UIProcess/WebFormClient.cpp
 UIProcess/WebFormSubmissionListenerProxy.cpp
@@ -532,6 +533,7 @@
 WebProcess/WebCoreSupport/WebChromeClient.cpp
 WebProcess/WebCoreSupport/WebColorChooser.cpp
 WebProcess/WebCoreSupport/WebContextMenuClient.cpp
+WebProcess/WebCoreSupport/WebDataListSuggestionPicker.cpp
 WebProcess/WebCoreSupport/WebDiagnosticLoggingClient.cpp
 WebProcess/WebCoreSupport/WebDragClient.cpp
 WebProcess/WebCoreSupport/WebEditorClient.cpp

Modified: trunk/Source/WebKit/SourcesCocoa.txt (248032 => 248033)


--- trunk/Source/WebKit/SourcesCocoa.txt	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Source/WebKit/SourcesCocoa.txt	2019-07-31 08:02:09 UTC (rev 248033)
@@ -218,7 +218,6 @@
 UIProcess/PerActivityStateCPUUsageSampler.cpp
 UIProcess/ViewGestureController.cpp
 UIProcess/ViewSnapshotStore.cpp
-UIProcess/WebDataListSuggestionsDropdown.cpp
 UIProcess/WebMediaSessionFocusManager.cpp
 UIProcess/WebMediaSessionFocusManagerClient.cpp
 UIProcess/WebMemoryPressureHandler.cpp
@@ -552,7 +551,6 @@
 WebProcess/Plugins/PDF/PDFPluginPasswordField.mm
 WebProcess/Plugins/PDF/PDFPluginTextAnnotation.mm
 
-WebProcess/WebCoreSupport/WebDataListSuggestionPicker.cpp
 WebProcess/WebCoreSupport/WebPasteboardOverrides.cpp
 WebProcess/WebCoreSupport/WebValidationMessageClient.cpp
 

Modified: trunk/Source/WebKit/SourcesGTK.txt (248032 => 248033)


--- trunk/Source/WebKit/SourcesGTK.txt	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Source/WebKit/SourcesGTK.txt	2019-07-31 08:02:09 UTC (rev 248033)
@@ -251,6 +251,7 @@
 UIProcess/gtk/WaylandCompositor.cpp @no-unify
 UIProcess/gtk/WebColorPickerGtk.cpp
 UIProcess/gtk/WebContextMenuProxyGtk.cpp
+UIProcess/gtk/WebDataListSuggestionsDropdownGtk.cpp
 UIProcess/gtk/WebInspectorProxyGtk.cpp
 UIProcess/gtk/WebKitInspectorWindow.cpp
 UIProcess/gtk/WebPageProxyGtk.cpp @no-unify

Modified: trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp (248032 => 248033)


--- trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp	2019-07-31 08:02:09 UTC (rev 248033)
@@ -35,6 +35,7 @@
 #include "ViewSnapshotStore.h"
 #include "WebColorPickerGtk.h"
 #include "WebContextMenuProxyGtk.h"
+#include "WebDataListSuggestionsDropdownGtk.h"
 #include "WebEventFactory.h"
 #include "WebKitColorChooser.h"
 #include "WebKitPopupMenu.h"
@@ -250,6 +251,13 @@
     return WebColorPickerGtk::create(*page, color, rect);
 }
 
+#if ENABLE(DATALIST_ELEMENT)
+RefPtr<WebDataListSuggestionsDropdown> PageClientImpl::createDataListSuggestionsDropdown(WebPageProxy& page)
+{
+    return WebDataListSuggestionsDropdownGtk::create(m_viewWidget, page);
+}
+#endif
+
 void PageClientImpl::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
 {
     webkitWebViewBaseEnterAcceleratedCompositingMode(WEBKIT_WEB_VIEW_BASE(m_viewWidget), layerTreeContext);

Modified: trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h (248032 => 248033)


--- trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h	2019-07-31 08:02:09 UTC (rev 248033)
@@ -94,6 +94,9 @@
 #if ENABLE(INPUT_TYPE_COLOR)
     RefPtr<WebColorPicker> createColorPicker(WebPageProxy*, const WebCore::Color& initialColor, const WebCore::IntRect&, Vector<WebCore::Color>&&) override;
 #endif
+#if ENABLE(DATALIST_ELEMENT)
+    RefPtr<WebDataListSuggestionsDropdown> createDataListSuggestionsDropdown(WebPageProxy&) override;
+#endif
     void selectionDidChange() override;
     RefPtr<ViewSnapshot> takeViewSnapshot() override;
 #if ENABLE(DRAG_SUPPORT)

Added: trunk/Source/WebKit/UIProcess/gtk/WebDataListSuggestionsDropdownGtk.cpp (0 => 248033)


--- trunk/Source/WebKit/UIProcess/gtk/WebDataListSuggestionsDropdownGtk.cpp	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/gtk/WebDataListSuggestionsDropdownGtk.cpp	2019-07-31 08:02:09 UTC (rev 248033)
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDataListSuggestionsDropdownGtk.h"
+
+#if ENABLE(DATALIST_ELEMENT)
+
+#include <WebCore/DataListSuggestionInformation.h>
+#include <wtf/glib/GRefPtr.h>
+#include <wtf/glib/GUniquePtr.h>
+
+namespace WebKit {
+
+static void firstTimeItemSelectedCallback(GtkTreeSelection* selection, GtkWidget* treeView)
+{
+    if (gtk_widget_is_focus(treeView))
+        gtk_tree_selection_unselect_all(selection);
+    g_signal_handlers_disconnect_by_func(selection, reinterpret_cast<gpointer>(firstTimeItemSelectedCallback), treeView);
+}
+
+WebDataListSuggestionsDropdownGtk::WebDataListSuggestionsDropdownGtk(GtkWidget* webView, WebPageProxy& page)
+    : WebDataListSuggestionsDropdown(page)
+    , m_webView(webView)
+{
+    GRefPtr<GtkListStore> model = adoptGRef(gtk_list_store_new(1, G_TYPE_STRING));
+    m_treeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model.get()));
+    auto* treeView = GTK_TREE_VIEW(m_treeView);
+    g_signal_connect(treeView, "row-activated", G_CALLBACK(treeViewRowActivatedCallback), this);
+    gtk_tree_view_set_enable_search(treeView, FALSE);
+    gtk_tree_view_set_activate_on_single_click(treeView, TRUE);
+    gtk_tree_view_set_hover_selection(treeView, TRUE);
+    gtk_tree_view_set_headers_visible(treeView, FALSE);
+    gtk_tree_view_insert_column_with_attributes(treeView, 0, nullptr, gtk_cell_renderer_text_new(), "text", 0, nullptr);
+
+    auto* selection = gtk_tree_view_get_selection(treeView);
+    // The first time it's shown the first item is always selected, so we connect to selection changed to unselect it.
+    g_signal_connect_object(selection, "changed", G_CALLBACK(firstTimeItemSelectedCallback), treeView, static_cast<GConnectFlags>(0));
+    gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+    auto* swindow = gtk_scrolled_window_new(nullptr, nullptr);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swindow), GTK_SHADOW_ETCHED_IN);
+    gtk_container_add(GTK_CONTAINER(swindow), m_treeView);
+    gtk_widget_show(m_treeView);
+
+    m_popup = gtk_window_new(GTK_WINDOW_POPUP);
+    gtk_window_set_type_hint(GTK_WINDOW(m_popup), GDK_WINDOW_TYPE_HINT_COMBO);
+    gtk_window_set_resizable(GTK_WINDOW(m_popup), FALSE);
+    gtk_container_add(GTK_CONTAINER(m_popup), swindow);
+    gtk_widget_show(swindow);
+
+    g_signal_connect_object(m_webView, "focus-out-event", G_CALLBACK(gtk_widget_hide), m_popup, G_CONNECT_SWAPPED);
+    g_signal_connect_object(m_webView, "unmap-event", G_CALLBACK(gtk_widget_hide), m_popup, G_CONNECT_SWAPPED);
+
+#if ENABLE(DEVELOPER_MODE)
+    g_object_set_data(G_OBJECT(m_webView), "wk-datalist-popup", m_popup);
+#endif
+}
+
+WebDataListSuggestionsDropdownGtk::~WebDataListSuggestionsDropdownGtk()
+{
+    gtk_window_set_transient_for(GTK_WINDOW(m_popup), nullptr);
+    gtk_window_set_attached_to(GTK_WINDOW(m_popup), nullptr);
+#if ENABLE(DEVELOPER_MODE)
+    g_object_set_data(G_OBJECT(m_webView), "wk-datalist-popup", nullptr);
+#endif
+    gtk_widget_destroy(m_popup);
+}
+
+void WebDataListSuggestionsDropdownGtk::treeViewRowActivatedCallback(GtkTreeView* treeView, GtkTreePath* path, GtkTreeViewColumn*, WebDataListSuggestionsDropdownGtk* menu)
+{
+    auto* model = gtk_tree_view_get_model(treeView);
+    GtkTreeIter iter;
+    gtk_tree_model_get_iter(model, &iter, path);
+    GUniqueOutPtr<char> item;
+    gtk_tree_model_get(model, &iter, 0, &item.outPtr(), -1);
+
+    menu->didSelectOption(String::fromUTF8(item.get()));
+}
+
+void WebDataListSuggestionsDropdownGtk::didSelectOption(const String& selectedOption)
+{
+    if (!m_page)
+        return;
+
+    m_page->didSelectOption(selectedOption);
+    close();
+}
+
+void WebDataListSuggestionsDropdownGtk::show(WebCore::DataListSuggestionInformation&& information)
+{
+    auto* model = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(m_treeView)));
+    gtk_list_store_clear(model);
+    for (const auto& suggestion : information.suggestions) {
+        GtkTreeIter iter;
+        gtk_list_store_append(model, &iter);
+        gtk_list_store_set(model, &iter, 0, suggestion.utf8().data(), -1);
+    }
+
+    GtkRequisition treeViewRequisition;
+    gtk_widget_get_preferred_size(m_treeView, &treeViewRequisition, nullptr);
+    auto* column = gtk_tree_view_get_column(GTK_TREE_VIEW(m_treeView), 0);
+    gint itemHeight;
+    gtk_tree_view_column_cell_get_size(column, nullptr, nullptr, nullptr, nullptr, &itemHeight);
+    gint verticalSeparator;
+    gtk_widget_style_get(m_treeView, "vertical-separator", &verticalSeparator, nullptr);
+    itemHeight += verticalSeparator;
+    if (!itemHeight)
+        return;
+
+    auto* display = gtk_widget_get_display(m_webView);
+    auto* monitor = gdk_display_get_monitor_at_window(display, gtk_widget_get_window(m_webView));
+    GdkRectangle area;
+    gdk_monitor_get_workarea(monitor, &area);
+    int width = std::min(information.elementRect.width(), area.width);
+    size_t itemCount = std::min<size_t>(information.suggestions.size(), (area.height / 3) / itemHeight);
+
+    auto* swindow = GTK_SCROLLED_WINDOW(gtk_bin_get_child(GTK_BIN(m_popup)));
+    // Disable scrollbars when there's only one item to ensure the scrolled window doesn't take them into account when calculating its minimum size.
+    gtk_scrolled_window_set_policy(swindow, GTK_POLICY_NEVER, itemCount > 1 ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER);
+    gtk_widget_realize(m_treeView);
+    gtk_tree_view_columns_autosize(GTK_TREE_VIEW(m_treeView));
+    gtk_scrolled_window_set_min_content_width(swindow, width);
+    gtk_widget_set_size_request(m_popup, width, -1);
+    gtk_scrolled_window_set_min_content_height(swindow, itemCount * itemHeight);
+
+    GtkRequisition menuRequisition;
+    gtk_widget_get_preferred_size(m_popup, &menuRequisition, nullptr);
+    IntPoint menuPosition = convertWidgetPointToScreenPoint(m_webView, information.elementRect.location());
+    // FIXME: We can't ensure the menu will be on screen in Wayland.
+    // https://blog.gtk.org/2016/07/15/future-of-relative-window-positioning/
+    // https://gitlab.gnome.org/GNOME/gtk/issues/997
+    if (menuPosition.x() + menuRequisition.width > area.x + area.width)
+        menuPosition.setX(area.x + area.width - menuRequisition.width);
+
+    if (menuPosition.y() + information.elementRect.height() + menuRequisition.height <= area.y + area.height
+        || menuPosition.y() - area.y < (area.y + area.height) - (menuPosition.y() + information.elementRect.height()))
+        menuPosition.move(0, information.elementRect.height());
+    else
+        menuPosition.move(0, -menuRequisition.height);
+    gtk_window_move(GTK_WINDOW(m_popup), menuPosition.x(), menuPosition.y());
+
+    auto* toplevel = gtk_widget_get_toplevel(m_webView);
+    if (GTK_IS_WINDOW(toplevel)) {
+        gtk_window_set_transient_for(GTK_WINDOW(m_popup), GTK_WINDOW(toplevel));
+        gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(toplevel)), GTK_WINDOW(m_popup));
+    }
+    gtk_window_set_attached_to(GTK_WINDOW(m_popup), m_webView);
+    gtk_window_set_screen(GTK_WINDOW(m_popup), gtk_widget_get_screen(m_webView));
+
+    gtk_widget_show(m_popup);
+}
+
+void WebDataListSuggestionsDropdownGtk::handleKeydownWithIdentifier(const String& key)
+{
+    auto* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(m_treeView));
+    GtkTreeModel* model;
+    GtkTreeIter iter;
+    bool hasSelection = gtk_tree_selection_get_selected(selection, &model, &iter);
+    if (key == "Enter") {
+        if (hasSelection) {
+            GUniqueOutPtr<char> item;
+            gtk_tree_model_get(model, &iter, 0, &item.outPtr(), -1);
+            m_page->didSelectOption(String::fromUTF8(item.get()));
+        }
+        close();
+        return;
+    }
+
+    if (key == "Up") {
+        if ((hasSelection && gtk_tree_model_iter_previous(model, &iter)) || gtk_tree_model_iter_nth_child(model, &iter, nullptr, gtk_tree_model_iter_n_children(model, nullptr) - 1))
+            gtk_tree_selection_select_iter(selection, &iter);
+        else
+            return;
+    } else if (key == "Down") {
+        if ((hasSelection && gtk_tree_model_iter_next(model, &iter)) || gtk_tree_model_get_iter_first(model, &iter))
+            gtk_tree_selection_select_iter(selection, &iter);
+        else
+            return;
+    }
+
+    GUniquePtr<GtkTreePath> path(gtk_tree_model_get_path(model, &iter));
+    gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(m_treeView), path.get(), nullptr, FALSE, 0, 0);
+}
+
+void WebDataListSuggestionsDropdownGtk::close()
+{
+    gtk_widget_hide(m_popup);
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(DATALIST_ELEMENT)

Copied: trunk/Source/WebKit/UIProcess/gtk/WebDataListSuggestionsDropdownGtk.h (from rev 248032, trunk/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h) (0 => 248033)


--- trunk/Source/WebKit/UIProcess/gtk/WebDataListSuggestionsDropdownGtk.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/gtk/WebDataListSuggestionsDropdownGtk.h	2019-07-31 08:02:09 UTC (rev 248033)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(DATALIST_ELEMENT)
+
+#include "WebDataListSuggestionsDropdown.h"
+
+typedef struct _GtkTreePath GtkTreePath;
+typedef struct _GtkTreeView GtkTreeView;
+typedef struct _GtkTreeViewColumn GtkTreeViewColumn;
+
+namespace WebKit {
+
+class WebPageProxy;
+
+class WebDataListSuggestionsDropdownGtk final : public WebDataListSuggestionsDropdown {
+public:
+    static Ref<WebDataListSuggestionsDropdownGtk> create(GtkWidget* webView, WebPageProxy& page)
+    {
+        return adoptRef(*new WebDataListSuggestionsDropdownGtk(webView, page));
+    }
+
+    ~WebDataListSuggestionsDropdownGtk();
+
+private:
+    WebDataListSuggestionsDropdownGtk(GtkWidget*, WebPageProxy&);
+
+    void show(WebCore::DataListSuggestionInformation&&) final;
+    void handleKeydownWithIdentifier(const String&) final;
+    void close() final;
+
+    static void treeViewRowActivatedCallback(GtkTreeView*, GtkTreePath*, GtkTreeViewColumn*, WebDataListSuggestionsDropdownGtk*);
+    void didSelectOption(const String&);
+
+    GtkWidget* m_webView { nullptr };
+    GtkWidget* m_popup { nullptr };
+    GtkWidget* m_treeView { nullptr };
+};
+
+} // namespace WebKit
+
+#endif // ENABLE(DATALIST_ELEMENT)

Modified: trunk/Source/cmake/OptionsGTK.cmake (248032 => 248033)


--- trunk/Source/cmake/OptionsGTK.cmake	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Source/cmake/OptionsGTK.cmake	2019-07-31 08:02:09 UTC (rev 248033)
@@ -150,6 +150,7 @@
 # Changing these options is completely unsupported.
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_CONTENT_EXTENSIONS PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DARK_MODE_CSS PRIVATE ON)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DATALIST_ELEMENT PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_DOWNLOAD_ATTRIBUTE PRIVATE ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_ENCRYPTED_MEDIA PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_FTPDIR PRIVATE OFF)

Modified: trunk/Tools/ChangeLog (248032 => 248033)


--- trunk/Tools/ChangeLog	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Tools/ChangeLog	2019-07-31 08:02:09 UTC (rev 248033)
@@ -1,3 +1,16 @@
+2019-07-31  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Datalist element support for TextFieldInputType
+        https://bugs.webkit.org/show_bug.cgi?id=98934
+
+        Reviewed by Michael Catanzaro.
+
+        Implement UIScriptControllerGtk::isShowingDataListSuggestions.
+
+        * WebKitTestRunner/gtk/UIScriptControllerGtk.cpp:
+        (WTR::UIScriptControllerGtk::isShowingDataListSuggestions const):
+        * WebKitTestRunner/gtk/UIScriptControllerGtk.h:
+
 2019-07-30  Tim Horton  <[email protected]>
 
         Remove some needless comments that snuck into the tree

Modified: trunk/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.cpp (248032 => 248033)


--- trunk/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.cpp	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.cpp	2019-07-31 08:02:09 UTC (rev 248033)
@@ -29,6 +29,7 @@
 #include "PlatformWebView.h"
 #include "TestController.h"
 #include <WebKit/WKViewPrivate.h>
+#include <gtk/gtk.h>
 
 namespace WTR {
 
@@ -51,4 +52,12 @@
     WKViewCompleteBackSwipeForTesting(webView);
 }
 
+bool UIScriptControllerGtk::isShowingDataListSuggestions() const
+{
+    auto* webView = TestController::singleton().mainWebView()->platformView();
+    if (auto* popup = g_object_get_data(G_OBJECT(webView), "wk-datalist-popup"))
+        return gtk_widget_get_mapped(GTK_WIDGET(popup));
+    return false;
+}
+
 } // namespace WTR

Modified: trunk/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h (248032 => 248033)


--- trunk/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h	2019-07-31 07:37:47 UTC (rev 248032)
+++ trunk/Tools/WebKitTestRunner/gtk/UIScriptControllerGtk.h	2019-07-31 08:02:09 UTC (rev 248033)
@@ -41,6 +41,7 @@
 
     void beginBackSwipe(JSValueRef) override;
     void completeBackSwipe(JSValueRef) override;
+    bool isShowingDataListSuggestions() const override;
 };
 
 } // namespace WTR
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to