Skip to content

Commit d2d8024

Browse files
committed
[WPE] WPE Platform: add disconnected signal to WPEDisplay
https://bugs.webkit.org/show_bug.cgi?id=303050 Reviewed by Adrian Perez de Castro. Emitted when the connection to the native display is lost. Tests: Tools/TestWebKitAPI/Tests/WPEPlatform/TestDisplay.cpp Canonical link: https://commits.webkit.org/303531@main
1 parent 9f179c4 commit d2d8024

File tree

7 files changed

+106
-14
lines changed

7 files changed

+106
-14
lines changed

‎Source/WebKit/WPEPlatform/wpe/WPEDisplay.cpp‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ enum {
8686
SCREEN_ADDED,
8787
SCREEN_REMOVED,
8888

89+
DISCONNECTED,
90+
8991
LAST_SIGNAL
9092
};
9193

@@ -205,6 +207,22 @@ static void wpe_display_class_init(WPEDisplayClass* displayClass)
205207
g_cclosure_marshal_generic,
206208
G_TYPE_NONE, 1,
207209
WPE_TYPE_SCREEN);
210+
211+
/**
212+
* WPEDisplay::disconnected:
213+
* @display: a #WPEDisplay
214+
* @error: (nullable): a #GError or %NULL
215+
*
216+
* Emitted when the @display is disconnected from the platform display.
217+
*/
218+
signals[DISCONNECTED] = g_signal_new(
219+
"disconnected",
220+
G_TYPE_FROM_CLASS(displayClass),
221+
G_SIGNAL_RUN_LAST,
222+
0, nullptr, nullptr,
223+
g_cclosure_marshal_generic,
224+
G_TYPE_NONE, 1,
225+
G_TYPE_ERROR);
208226
}
209227

210228
WPEView* wpeDisplayCreateView(WPEDisplay* display)
@@ -322,6 +340,23 @@ gboolean wpe_display_connect(WPEDisplay* display, GError** error)
322340
return wpeDisplayClass->connect(display, error);
323341
}
324342

343+
/**
344+
* wpe_display_disconnected:
345+
* @display: a #WPEDisplay
346+
* @error: (nullable): a #GError or %NULL
347+
*
348+
* Emit the signal #WPEDisplay::disconnected with the given @error
349+
*
350+
* This function should only be called by platform implementations.
351+
*/
352+
void wpe_display_disconnected(WPEDisplay* display, GError* error)
353+
{
354+
g_return_if_fail(WPE_IS_DISPLAY(display));
355+
g_return_if_fail(!error || g_error_matches(error, WPE_DISPLAY_ERROR, WPE_DISPLAY_ERROR_CONNECTION_LOST));
356+
357+
g_signal_emit(display, signals[DISCONNECTED], 0, error);
358+
}
359+
325360
/**
326361
* wpe_display_get_egl_display: (skip)
327362
* @display: a #WPEDisplay

‎Source/WebKit/WPEPlatform/wpe/WPEDisplay.h‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ struct _WPEDisplayClass
9191
*/
9292
typedef enum {
9393
WPE_DISPLAY_ERROR_NOT_SUPPORTED,
94-
WPE_DISPLAY_ERROR_CONNECTION_FAILED
94+
WPE_DISPLAY_ERROR_CONNECTION_FAILED,
95+
WPE_DISPLAY_ERROR_CONNECTION_LOST
9596
} WPEDisplayError;
9697

9798
WPE_API GQuark wpe_display_error_quark (void);
@@ -100,6 +101,8 @@ WPE_API WPEDisplay *wpe_display_get_primary (void
100101
WPE_API void wpe_display_set_primary (WPEDisplay *display);
101102
WPE_API gboolean wpe_display_connect (WPEDisplay *display,
102103
GError **error);
104+
WPE_API void wpe_display_disconnected (WPEDisplay *display,
105+
GError *error);
103106
WPE_API gpointer wpe_display_get_egl_display (WPEDisplay *display,
104107
GError **error);
105108
WPE_API WPEKeymap *wpe_display_get_keymap (WPEDisplay *display);

‎Source/WebKit/WPEPlatform/wpe/wayland/WPEDisplayWayland.cpp‎

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
#include <wtf/SystemTracing.h>
5454
#include <wtf/Vector.h>
5555
#include <wtf/glib/GRefPtr.h>
56+
#include <wtf/glib/GUniquePtr.h>
5657
#include <wtf/glib/WTFGType.h>
5758
#include <wtf/text/CString.h>
5859
#include <wtf/text/StringView.h>
@@ -114,53 +115,68 @@ struct EventSource {
114115

115116
GSource source;
116117
GPollFD pfd;
117-
struct wl_display* display;
118+
WPEDisplayWayland* display;
118119
};
119120

120121
GSourceFuncs EventSource::sourceFuncs = {
121122
// prepare
122123
[](GSource* base, gint* timeout) -> gboolean
123124
{
124125
auto* source = reinterpret_cast<EventSource*>(base);
125-
struct wl_display* display = source->display;
126+
auto* display = WPE_DISPLAY_WAYLAND(source->display);
126127

127128
*timeout = -1;
128129

129-
while (wl_display_prepare_read(display)) {
130-
if (wl_display_dispatch_pending(display) < 0)
130+
while (wl_display_prepare_read(display->priv->wlDisplay)) {
131+
if (wl_display_dispatch_pending(display->priv->wlDisplay) < 0)
131132
return FALSE;
132133
}
133134

134-
wl_display_flush(display);
135+
wl_display_flush(display->priv->wlDisplay);
135136

136137
return FALSE;
137138
},
138139
// check
139140
[](GSource* base) -> gboolean
140141
{
141142
auto* source = reinterpret_cast<EventSource*>(base);
142-
struct wl_display* display = source->display;
143+
auto* display = WPE_DISPLAY_WAYLAND(source->display);
144+
145+
if (source->pfd.revents & (G_IO_ERR | G_IO_HUP)) {
146+
GUniquePtr<GError> error(g_error_new_literal(WPE_DISPLAY_ERROR, WPE_DISPLAY_ERROR_CONNECTION_LOST, "Connection to Wayland compositor was lost"));
147+
wpe_display_disconnected(WPE_DISPLAY(display), error.get());
148+
return FALSE;
149+
}
143150

144151
if (source->pfd.revents & G_IO_IN) {
145-
if (wl_display_read_events(display) < 0)
152+
if (wl_display_read_events(display->priv->wlDisplay) < 0) {
153+
GUniquePtr<GError> error(g_error_new(WPE_DISPLAY_ERROR, WPE_DISPLAY_ERROR_CONNECTION_LOST, "Error reading events from Wayland display: %s", g_strerror(errno)));
154+
wpe_display_disconnected(WPE_DISPLAY(display), error.get());
146155
return FALSE;
156+
}
147157
} else
148-
wl_display_cancel_read(display);
158+
wl_display_cancel_read(display->priv->wlDisplay);
149159

150160
return !!source->pfd.revents;
151161
},
152162
// dispatch
153163
[](GSource* base, GSourceFunc, gpointer) -> gboolean
154164
{
155165
auto* source = reinterpret_cast<EventSource*>(base);
156-
struct wl_display* display = source->display;
166+
auto* display = WPE_DISPLAY_WAYLAND(source->display);
157167

158-
if (source->pfd.revents & (G_IO_ERR | G_IO_HUP))
168+
if (source->pfd.revents & (G_IO_ERR | G_IO_HUP)) {
169+
GUniquePtr<GError> error(g_error_new_literal(WPE_DISPLAY_ERROR, WPE_DISPLAY_ERROR_CONNECTION_LOST, "Connection to Wayland compositor was lost"));
170+
wpe_display_disconnected(WPE_DISPLAY(display), error.get());
159171
return FALSE;
172+
}
160173

161174
if (source->pfd.revents & G_IO_IN) {
162-
if (wl_display_dispatch_pending(display) < 0)
175+
if (wl_display_dispatch_pending(display->priv->wlDisplay) < 0) {
176+
GUniquePtr<GError> error(g_error_new(WPE_DISPLAY_ERROR, WPE_DISPLAY_ERROR_CONNECTION_LOST, "Error disaptching events to Wayland display: %s", g_strerror(errno)));
177+
wpe_display_disconnected(WPE_DISPLAY(display), error.get());
163178
return FALSE;
179+
}
164180
}
165181

166182
source->pfd.revents = 0;
@@ -175,8 +191,8 @@ static GRefPtr<GSource> wpeDisplayWaylandCreateEventSource(WPEDisplayWayland* di
175191
{
176192
auto source = adoptGRef(g_source_new(&EventSource::sourceFuncs, sizeof(EventSource)));
177193
auto& eventSource = *reinterpret_cast<EventSource*>(source.get());
178-
eventSource.display = display->priv->wlDisplay;
179-
eventSource.pfd.fd = wl_display_get_fd(eventSource.display);
194+
eventSource.display = display;
195+
eventSource.pfd.fd = wl_display_get_fd(display->priv->wlDisplay);
180196
eventSource.pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP;
181197
eventSource.pfd.revents = 0;
182198
g_source_add_poll(&eventSource.source, &eventSource.pfd);

‎Tools/MiniBrowser/wpe/main.cpp‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,15 @@ static void webViewTitleChanged(WebKitWebView* webView, GParamSpec*, WPEView* vi
265265
wpe_toplevel_set_title(wpe_view_get_toplevel(view), privateTitle ? privateTitle : title);
266266
g_free(privateTitle);
267267
}
268+
269+
static void displayDisconnected(WPEDisplay*, GError* error)
270+
{
271+
if (error)
272+
g_warning("WPE display disconnected: %s", error->message);
273+
else
274+
g_warning("WPE display disconnected");
275+
_exit(1);
276+
}
268277
#endif
269278

270279

@@ -617,6 +626,7 @@ static void activate(GApplication* application, WPEToolingBackends::ViewBackend*
617626

618627
#if ENABLE_WPE_PLATFORM
619628
if (auto* wpeView = webkit_web_view_get_wpe_view(webView)) {
629+
g_signal_connect(wpe_view_get_display(wpeView), "disconnected", G_CALLBACK(displayDisconnected), nullptr);
620630
auto* wpeToplevel = wpe_view_get_toplevel(wpeView);
621631
if (windowWidth > 0 && windowHeight > 0)
622632
wpe_toplevel_resize(wpeToplevel, windowWidth, windowHeight);

‎Tools/TestWebKitAPI/Tests/WPEPlatform/TestDisplay.cpp‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,24 @@ static void testDisplayConnect(WPEMockPlatformTest* test, gconstpointer)
4848
g_assert_error(error.get(), WPE_DISPLAY_ERROR, WPE_DISPLAY_ERROR_CONNECTION_FAILED);
4949
}
5050

51+
static void testDisplayDisconnected(WPEMockPlatformTest* test, gconstpointer)
52+
{
53+
GUniqueOutPtr<GError> error;
54+
g_assert_true(wpe_display_connect(test->display(), &error.outPtr()));
55+
g_assert_no_error(error.get());
56+
57+
gboolean displayDisconnected = FALSE;
58+
auto displayDisconnectedID = g_signal_connect(test->display(), "disconnected", G_CALLBACK(+[](WPEDisplay*, GError* error, gboolean* displayDisconnected) {
59+
*displayDisconnected = TRUE;
60+
g_assert_error(error, WPE_DISPLAY_ERROR, WPE_DISPLAY_ERROR_CONNECTION_LOST);
61+
}), &displayDisconnected);
62+
63+
wpeDisplayMockDisconnect(WPE_DISPLAY_MOCK(test->display()));
64+
g_assert_true(displayDisconnected);
65+
66+
g_signal_handler_disconnect(test->display(), displayDisconnectedID);
67+
}
68+
5169
static void testDisplayPrimary(WPEMockPlatformTest* test, gconstpointer)
5270
{
5371
// The first created display is always the primary.
@@ -294,6 +312,7 @@ static void testDisplayCreateView(WPEMockPlatformTest* test, gconstpointer)
294312
void beforeAll()
295313
{
296314
WPEMockPlatformTest::add("Display", "connect", testDisplayConnect);
315+
WPEMockPlatformTest::add("Display", "disconnected", testDisplayDisconnected);
297316
WPEMockPlatformTest::add("Display", "primary", testDisplayPrimary);
298317
WPEMockPlatformTest::add("Display", "keymap", testDisplayKeymap);
299318
WPEMockPlatformTest::add("Display", "drm-nodes", testDisplayDRMNodes);

‎Tools/TestWebKitAPI/glib/WPEPlatform/mock/WPEDisplayMock.cpp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,14 @@ void wpeDisplayMockRegister(GIOModule* ioModule)
212212
g_io_extension_point_implement(WPE_DISPLAY_EXTENSION_POINT_NAME, WPE_TYPE_DISPLAY_MOCK, "wpe-display-mock", G_MAXINT32);
213213
}
214214

215+
void wpeDisplayMockDisconnect(WPEDisplayMock* mock)
216+
{
217+
mock->isConnected = FALSE;
218+
GError* error = g_error_new_literal(WPE_DISPLAY_ERROR, WPE_DISPLAY_ERROR_CONNECTION_LOST, "Display disconnected");
219+
wpe_display_disconnected(WPE_DISPLAY(mock), error);
220+
g_error_free(error);
221+
}
222+
215223
void wpeDisplayMockUseFakeDRMNodes(WPEDisplayMock* mock, gboolean useFakeDRMNodes)
216224
{
217225
if (!useFakeDRMNodes) {

‎Tools/TestWebKitAPI/glib/WPEPlatform/mock/WPEDisplayMock.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ G_DECLARE_FINAL_TYPE(WPEDisplayMock, wpe_display_mock, WPE, DISPLAY_MOCK, WPEDis
3636

3737
void wpeDisplayMockRegister(GIOModule*);
3838
WPEDisplay* wpeDisplayMockNew();
39+
void wpeDisplayMockDisconnect(WPEDisplayMock*);
3940
void wpeDisplayMockUseFakeDRMNodes(WPEDisplayMock*, gboolean);
4041
void wpeDisplayMockUseFakeDMABufFormats(WPEDisplayMock*, gboolean);
4142
void wpeDisplayMockSetUseExplicitSync(WPEDisplayMock*, gboolean);

0 commit comments

Comments
 (0)