Diff
Modified: trunk/Source/WebCore/ChangeLog (262413 => 262414)
--- trunk/Source/WebCore/ChangeLog 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Source/WebCore/ChangeLog 2020-06-02 13:04:55 UTC (rev 262414)
@@ -1,3 +1,13 @@
+2020-06-02 Carlos Garcia Campos <cgar...@igalia.com>
+
+ [GTK4] Make popup menus work
+ https://bugs.webkit.org/show_bug.cgi?id=211178
+
+ Reviewed by Adrian Perez de Castro.
+
+ * platform/gtk/GtkVersioning.h:
+ (gtk_tree_view_column_cell_get_size):
+
2020-06-01 Sergio Villar Senin <svil...@igalia.com>
[css-flexbox] ChildIntrinsicLogicalWidth should use fit-content, not max-content
Modified: trunk/Source/WebCore/platform/gtk/GtkVersioning.h (262413 => 262414)
--- trunk/Source/WebCore/platform/gtk/GtkVersioning.h 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Source/WebCore/platform/gtk/GtkVersioning.h 2020-06-02 13:04:55 UTC (rev 262414)
@@ -221,6 +221,12 @@
return context.response;
}
+static inline void
+gtk_tree_view_column_cell_get_size(GtkTreeViewColumn* column, const GdkRectangle*, gint* xOffset, gint* yOffset, gint* width, gint* height)
+{
+ gtk_tree_view_column_cell_get_size(column, xOffset, yOffset, width, height);
+}
+
#else // USE(GTK4)
static inline void
Modified: trunk/Source/WebKit/ChangeLog (262413 => 262414)
--- trunk/Source/WebKit/ChangeLog 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Source/WebKit/ChangeLog 2020-06-02 13:04:55 UTC (rev 262414)
@@ -1,3 +1,32 @@
+2020-06-02 Carlos Garcia Campos <cgar...@igalia.com>
+
+ [GTK4] Make popup menus work
+ https://bugs.webkit.org/show_bug.cgi?id=211178
+
+ Reviewed by Adrian Perez de Castro.
+
+ Use a GtkPopover for GTK4 instead of a GtkMenu.
+
+ * UIProcess/API/gtk/PageClientImpl.cpp:
+ (WebKit::PageClientImpl::createPopupMenuProxy):
+ * UIProcess/API/gtk/WebKitPopupMenu.cpp:
+ (WebKit::WebKitPopupMenu::WebKitPopupMenu):
+ (WebKit::menuCloseCallback):
+ (WebKit::WebKitPopupMenu::showPopupMenu):
+ (WebKit::WebKitPopupMenu::hidePopupMenu):
+ (WebKit::WebKitPopupMenu::cancelTracking):
+ (WebKit::WebKitPopupMenu::activateItem):
+ * UIProcess/API/gtk/WebKitPopupMenu.h:
+ * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+ (webkitWebViewBaseSizeAllocate): Iterate children and call check_resize on every native one.
+ * UIProcess/gtk/WebPopupMenuProxyGtk.cpp:
+ (WebKit::WebPopupMenuProxyGtk::treeViewButtonReleaseEventCallback):
+ (WebKit::WebPopupMenuProxyGtk::createPopupMenu):
+ (WebKit::WebPopupMenuProxyGtk::showPopupMenu):
+ (WebKit::WebPopupMenuProxyGtk::hidePopupMenu):
+ (WebKit::WebPopupMenuProxyGtk::treeViewRowActivatedCallback): Deleted.
+ * UIProcess/gtk/WebPopupMenuProxyGtk.h:
+
2020-06-01 Chris Dumez <cdu...@apple.com>
Fix thread-safety issue in [WKProcessAssertionBackgroundTaskManager _handleBackgroundTaskExpiration]
Modified: trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp (262413 => 262414)
--- trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp 2020-06-02 13:04:55 UTC (rev 262414)
@@ -253,13 +253,9 @@
RefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy& page)
{
-#if USE(GTK4)
- return nullptr;
-#else
if (WEBKIT_IS_WEB_VIEW(m_viewWidget))
return WebKitPopupMenu::create(m_viewWidget, page);
return WebPopupMenuProxyGtk::create(m_viewWidget, page);
-#endif
}
Ref<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy& page, ContextMenuContextData&& context, const UserData& userData)
Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitPopupMenu.cpp (262413 => 262414)
--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitPopupMenu.cpp 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitPopupMenu.cpp 2020-06-02 13:04:55 UTC (rev 262414)
@@ -28,24 +28,17 @@
using namespace WebCore;
WebKitPopupMenu::WebKitPopupMenu(GtkWidget* webView, WebPopupMenuProxy::Client& client)
-#if USE(GTK4)
- : WebPopupMenuProxy(client)
-#else
: WebPopupMenuProxyGtk(webView, client)
-#endif
{
}
-#if !USE(GTK4)
static void menuCloseCallback(WebKitPopupMenu* popupMenu)
{
popupMenu->activateItem(WTF::nullopt);
}
-#endif
void WebKitPopupMenu::showPopupMenu(const IntRect& rect, TextDirection direction, double pageScaleFactor, const Vector<WebPopupItem>& items, const PlatformPopupMenuData& platformData, int32_t selectedIndex)
{
-#if !USE(GTK4)
GRefPtr<WebKitOptionMenu> menu = adoptGRef(webkitOptionMenuCreate(*this, items, selectedIndex));
const GdkEvent* event = m_client->currentlyProcessedMouseDownEvent() ? m_client->currentlyProcessedMouseDownEvent()->nativeEvent() : nullptr;
if (webkitWebViewShowOptionMenu(WEBKIT_WEB_VIEW(m_webView), rect, menu.get(), event)) {
@@ -53,12 +46,10 @@
g_signal_connect_swapped(m_menu.get(), "close", G_CALLBACK(menuCloseCallback), this);
} else
WebPopupMenuProxyGtk::showPopupMenu(rect, direction, pageScaleFactor, items, platformData, selectedIndex);
-#endif
}
void WebKitPopupMenu::hidePopupMenu()
{
-#if !USE(GTK4)
if (!m_menu) {
WebPopupMenuProxyGtk::hidePopupMenu();
return;
@@ -65,12 +56,10 @@
}
g_signal_handlers_disconnect_matched(m_menu.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
webkit_option_menu_close(m_menu.get());
-#endif
}
void WebKitPopupMenu::cancelTracking()
{
-#if !USE(GTK4)
if (!m_menu) {
WebPopupMenuProxyGtk::cancelTracking();
return;
@@ -77,10 +66,8 @@
}
hidePopupMenu();
m_menu = nullptr;
-#endif
}
-#if !USE(GTK4)
void WebKitPopupMenu::activateItem(Optional<unsigned> itemIndex)
{
WebPopupMenuProxyGtk::activateItem(itemIndex);
@@ -89,6 +76,5 @@
m_menu = nullptr;
}
}
-#endif
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitPopupMenu.h (262413 => 262414)
--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitPopupMenu.h 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitPopupMenu.h 2020-06-02 13:04:55 UTC (rev 262414)
@@ -26,11 +26,7 @@
namespace WebKit {
-#if USE(GTK4)
-class WebKitPopupMenu final : public WebPopupMenuProxy {
-#else
class WebKitPopupMenu final : public WebPopupMenuProxyGtk {
-#endif
public:
static Ref<WebKitPopupMenu> create(GtkWidget* webView, WebPopupMenuProxy::Client& client)
{
@@ -38,12 +34,7 @@
}
~WebKitPopupMenu() = default;
-#if USE(GTK4)
- void selectItem(unsigned) { };
- void activateItem(Optional<unsigned>) { };
-#else
void activateItem(Optional<unsigned> itemIndex) override;
-#endif
private:
WebKitPopupMenu(GtkWidget*, WebPopupMenuProxy::Client&);
@@ -52,9 +43,7 @@
void hidePopupMenu() override;
void cancelTracking() override;
-#if !USE(GTK4)
GRefPtr<WebKitOptionMenu> m_menu;
-#endif
};
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp (262413 => 262414)
--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp 2020-06-02 13:04:55 UTC (rev 262414)
@@ -853,8 +853,10 @@
}
#if USE(GTK4)
- if (priv->activeContextMenuProxy)
- gtk_native_check_resize(GTK_NATIVE(priv->activeContextMenuProxy->gtkWidget()));
+ for (auto* child = gtk_widget_get_first_child(widget); child; child = gtk_widget_get_next_sibling(child)) {
+ if (GTK_IS_NATIVE(child))
+ gtk_native_check_resize(GTK_NATIVE(child));
+ }
#endif
if (auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(priv->pageProxy->drawingArea()))
Modified: trunk/Source/WebKit/UIProcess/gtk/WebPopupMenuProxyGtk.cpp (262413 => 262414)
--- trunk/Source/WebKit/UIProcess/gtk/WebPopupMenuProxyGtk.cpp 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Source/WebKit/UIProcess/gtk/WebPopupMenuProxyGtk.cpp 2020-06-02 13:04:55 UTC (rev 262414)
@@ -26,11 +26,10 @@
#include "config.h"
#include "WebPopupMenuProxyGtk.h"
-#if !USE(GTK4)
-
#include "NativeWebMouseEvent.h"
#include "WebPopupItem.h"
#include <WebCore/GtkUtilities.h>
+#include <WebCore/GtkVersioning.h>
#include <WebCore/IntRect.h>
#include <gtk/gtk.h>
#include <wtf/glib/GUniquePtr.h>
@@ -114,20 +113,16 @@
activateItemAtPath(path.get());
}
-void WebPopupMenuProxyGtk::treeViewRowActivatedCallback(GtkTreeView*, GtkTreePath* path, GtkTreeViewColumn*, WebPopupMenuProxyGtk* popupMenu)
+#if !USE(GTK4)
+gboolean WebPopupMenuProxyGtk::treeViewButtonReleaseEventCallback(GtkWidget* treeView, GdkEvent* event, WebPopupMenuProxyGtk* popupMenu)
{
- popupMenu->activateItemAtPath(path);
-}
-
-gboolean WebPopupMenuProxyGtk::treeViewButtonReleaseEventCallback(GtkWidget* treeView, GdkEventButton* event, WebPopupMenuProxyGtk* popupMenu)
-{
guint button;
- gdk_event_get_button(reinterpret_cast<GdkEvent*>(event), &button);
+ gdk_event_get_button(event, &button);
if (button != GDK_BUTTON_PRIMARY)
return FALSE;
double x, y;
- gdk_event_get_coords(reinterpret_cast<GdkEvent*>(event), &x, &y);
+ gdk_event_get_coords(event, &x, &y);
GUniqueOutPtr<GtkTreePath> path;
if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeView), x, y, &path.outPtr(), nullptr, nullptr, nullptr))
return FALSE;
@@ -158,6 +153,7 @@
gtk_widget_event(popupMenu->m_treeView, event);
return TRUE;
}
+#endif
void WebPopupMenuProxyGtk::createPopupMenu(const Vector<WebPopupItem>& items, int32_t selectedIndex)
{
@@ -198,8 +194,13 @@
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);
+ g_signal_connect_swapped(treeView, "row-activated", G_CALLBACK(+[](WebPopupMenuProxyGtk* popupMenu, GtkTreePath* path) {
+ popupMenu->activateItemAtPath(path);
+ }), this);
+
+#if !USE(GTK4)
g_signal_connect_after(treeView, "button-release-event", G_CALLBACK(treeViewButtonReleaseEventCallback), this);
+#endif
gtk_tree_view_set_tooltip_column(treeView, Columns::Tooltip);
gtk_tree_view_set_show_expanders(treeView, FALSE);
gtk_tree_view_set_level_indentation(treeView, 12);
@@ -232,10 +233,33 @@
auto* swindow = gtk_scrolled_window_new(nullptr, nullptr);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+#if USE(GTK4)
+ gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(swindow), m_treeView);
+#else
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);
+#endif
+#if USE(GTK4)
+ m_popup = gtk_popover_new();
+ g_signal_connect_swapped(m_popup, "closed", G_CALLBACK(+[](WebPopupMenuProxyGtk* popupMenu) {
+ popupMenu->hidePopupMenu();
+ }), this);
+ gtk_popover_set_has_arrow(GTK_POPOVER(m_popup), FALSE);
+ gtk_popover_set_position(GTK_POPOVER(m_popup), GTK_POS_BOTTOM);
+ gtk_popover_set_child(GTK_POPOVER(m_popup), swindow);
+ gtk_widget_set_parent(m_popup, m_webView);
+
+ auto* controller = gtk_event_controller_key_new();
+ g_signal_connect_swapped(controller, "key-pressed", G_CALLBACK(+[](WebPopupMenuProxyGtk* popupMenu, unsigned keyval, unsigned, GdkModifierType, GtkEventController* controller) {
+ auto* event = gtk_event_controller_get_current_event(controller);
+ if (popupMenu->typeAheadFind(keyval, gdk_event_get_time(event)))
+ return GDK_EVENT_STOP;
+ return gtk_event_controller_key_forward(GTK_EVENT_CONTROLLER_KEY(controller), popupMenu->m_treeView);
+ }), this);
+ gtk_widget_add_controller(m_popup, controller);
+#else
m_popup = gtk_window_new(GTK_WINDOW_POPUP);
g_signal_connect(m_popup, "button-press-event", G_CALLBACK(buttonPressEventCallback), this);
g_signal_connect(m_popup, "key-press-event", G_CALLBACK(keyPressEventCallback), this);
@@ -243,6 +267,7 @@
gtk_window_set_resizable(GTK_WINDOW(m_popup), FALSE);
gtk_container_add(GTK_CONTAINER(m_popup), swindow);
gtk_widget_show(swindow);
+#endif
}
void WebPopupMenuProxyGtk::show()
@@ -267,12 +292,15 @@
auto* column = gtk_tree_view_get_column(GTK_TREE_VIEW(m_treeView), Columns::Label);
gint itemHeight;
gtk_tree_view_column_cell_get_size(column, nullptr, nullptr, nullptr, nullptr, &itemHeight);
+#if !USE(GTK4)
gint verticalSeparator;
gtk_widget_style_get(m_treeView, "vertical-separator", &verticalSeparator, nullptr);
itemHeight += verticalSeparator;
+#endif
if (!itemHeight)
return;
+#if !USE(GTK4)
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));
@@ -280,15 +308,24 @@
}
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));
+#endif
auto* display = gtk_widget_get_display(m_webView);
+#if USE(GTK4)
+ auto* monitor = gdk_display_get_monitor_at_surface(display, gtk_native_get_surface(gtk_widget_get_native(m_webView)));
+#else
auto* monitor = gdk_display_get_monitor_at_window(display, gtk_widget_get_window(m_webView));
+#endif
GdkRectangle area;
gdk_monitor_get_workarea(monitor, &area);
int width = std::min(rect.width(), area.width);
size_t itemCount = std::min<size_t>(items.size(), (area.height / 3) / itemHeight);
+#if USE(GTK4)
+ auto* swindow = GTK_SCROLLED_WINDOW(gtk_popover_get_child(GTK_POPOVER(m_popup)));
+#else
auto* swindow = GTK_SCROLLED_WINDOW(gtk_bin_get_child(GTK_BIN(m_popup)));
+#endif
// 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);
@@ -297,6 +334,11 @@
gtk_widget_set_size_request(m_popup, width, -1);
gtk_scrolled_window_set_min_content_height(swindow, itemCount * itemHeight);
+#if USE(GTK4)
+ GdkRectangle windowRect = { rect.x(), rect.y(), rect.width(), rect.height() };
+ gtk_popover_set_pointing_to(GTK_POPOVER(m_popup), &windowRect);
+ show();
+#else
#if GTK_CHECK_VERSION(3, 24, 0)
GdkRectangle windowRect = { rect.x(), rect.y(), rect.width(), rect.height() };
gtk_widget_translate_coordinates(m_webView, toplevel, windowRect.x, windowRect.y, &windowRect.x, &windowRect.y);
@@ -341,6 +383,7 @@
m_client->failedToShowPopupMenu();
return;
}
+#endif
}
void WebPopupMenuProxyGtk::hidePopupMenu()
@@ -348,6 +391,7 @@
if (!m_popup)
return;
+#if !USE(GTK4)
if (m_device) {
gdk_seat_ungrab(gdk_device_get_seat(m_device));
gtk_grab_remove(m_popup);
@@ -355,6 +399,7 @@
gtk_window_set_attached_to(GTK_WINDOW(m_popup), nullptr);
m_device = nullptr;
}
+#endif
activateItem(WTF::nullopt);
@@ -363,8 +408,12 @@
m_currentSearchString = nullptr;
}
+#if USE(GTK4)
+ g_clear_pointer(&m_popup, gtk_widget_unparent);
+#else
gtk_widget_destroy(m_popup);
m_popup = nullptr;
+#endif
}
void WebPopupMenuProxyGtk::cancelTracking()
@@ -459,5 +508,3 @@
}
} // namespace WebKit
-
-#endif
Modified: trunk/Source/WebKit/UIProcess/gtk/WebPopupMenuProxyGtk.h (262413 => 262414)
--- trunk/Source/WebKit/UIProcess/gtk/WebPopupMenuProxyGtk.h 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Source/WebKit/UIProcess/gtk/WebPopupMenuProxyGtk.h 2020-06-02 13:04:55 UTC (rev 262414)
@@ -20,19 +20,20 @@
#pragma once
#include "WebPopupMenuProxy.h"
-#if !USE(GTK4)
#include <WebCore/GUniquePtrGtk.h>
#include <wtf/Vector.h>
#include <wtf/glib/GRefPtr.h>
#include <wtf/text/WTFString.h>
-typedef struct _GMainLoop GMainLoop;
typedef struct _GdkDevice GdkDevice;
-typedef struct _GdkEventButton GdkEventButton;
typedef struct _GtkTreePath GtkTreePath;
typedef struct _GtkTreeView GtkTreeView;
typedef struct _GtkTreeViewColumn GtkTreeViewColumn;
+#if USE(GTK4)
+typedef struct _GdkEvent GdkEvent;
+#else
typedef union _GdkEvent GdkEvent;
+#endif
namespace WebCore {
class IntRect;
@@ -72,14 +73,17 @@
Optional<unsigned> typeAheadFindIndex(unsigned keyval, uint32_t timestamp);
bool typeAheadFind(unsigned keyval, uint32_t timestamp);
+#if !USE(GTK4)
static gboolean buttonPressEventCallback(GtkWidget*, GdkEventButton*, WebPopupMenuProxyGtk*);
static gboolean keyPressEventCallback(GtkWidget*, GdkEvent*, WebPopupMenuProxyGtk*);
- static void treeViewRowActivatedCallback(GtkTreeView*, GtkTreePath*, GtkTreeViewColumn*, WebPopupMenuProxyGtk*);
- static gboolean treeViewButtonReleaseEventCallback(GtkWidget*, GdkEventButton*, WebPopupMenuProxyGtk*);
+ static gboolean treeViewButtonReleaseEventCallback(GtkWidget*, GdkEvent*, WebPopupMenuProxyGtk*);
+#endif
GtkWidget* m_popup { nullptr };
GtkWidget* m_treeView { nullptr };
+#if !USE(GTK4)
GdkDevice* m_device { nullptr };
+#endif
Vector<GUniquePtr<GtkTreePath>> m_paths;
Optional<unsigned> m_selectedItem;
@@ -91,5 +95,3 @@
};
} // namespace WebKit
-
-#endif
Modified: trunk/Tools/ChangeLog (262413 => 262414)
--- trunk/Tools/ChangeLog 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Tools/ChangeLog 2020-06-02 13:04:55 UTC (rev 262414)
@@ -1,5 +1,15 @@
2020-06-02 Carlos Garcia Campos <cgar...@igalia.com>
+ [GTK4] Make popup menus work
+ https://bugs.webkit.org/show_bug.cgi?id=211178
+
+ Reviewed by Adrian Perez de Castro.
+
+ * WebKitTestRunner/gtk/PlatformWebViewGtk.cpp:
+ (WTR::PlatformWebView::dismissAllPopupMenus):
+
+2020-06-02 Carlos Garcia Campos <cgar...@igalia.com>
+
[GTK4] Make it possible to run layout tests
https://bugs.webkit.org/show_bug.cgi?id=212328
Modified: trunk/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp (262413 => 262414)
--- trunk/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp 2020-06-02 12:52:16 UTC (rev 262413)
+++ trunk/Tools/WebKitTestRunner/gtk/PlatformWebViewGtk.cpp 2020-06-02 13:04:55 UTC (rev 262414)
@@ -247,7 +247,12 @@
void PlatformWebView::dismissAllPopupMenus()
{
-#if !USE(GTK4)
+#if USE(GTK4)
+ for (auto* child = gtk_widget_get_first_child(GTK_WIDGET(m_view)); child; child = gtk_widget_get_next_sibling(child)) {
+ if (GTK_IS_POPOVER(child))
+ gtk_widget_unparent(child);
+ }
+#else
// gtk_menu_popdown doesn't modify the GList of attached menus, so it should
// be safe to walk this list while calling it.
GList* attachedMenusList = gtk_menu_get_for_attach_widget(GTK_WIDGET(m_view));