wayland: Handle dispatch errors when showing a window
If a dispatch event when showing a window returns a failure code, handle the display disconnected condition and break out of the loop, otherwise, it will hang forever.
This commit is contained in:
@@ -671,20 +671,8 @@ void Wayland_PumpEvents(SDL_VideoDevice *_this)
|
|||||||
}
|
}
|
||||||
|
|
||||||
connection_error:
|
connection_error:
|
||||||
if (ret < 0 && !d->display_disconnected) {
|
if (ret < 0) {
|
||||||
/* Something has failed with the Wayland connection -- for example,
|
Wayland_HandleDisplayDisconnected(_this);
|
||||||
* the compositor may have shut down and closed its end of the socket,
|
|
||||||
* or there is a library-specific error.
|
|
||||||
*
|
|
||||||
* Try to recover once, then quit.
|
|
||||||
*/
|
|
||||||
if (!Wayland_VideoReconnect(_this)) {
|
|
||||||
d->display_disconnected = 1;
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Wayland display connection closed by server (fatal)");
|
|
||||||
|
|
||||||
// Only send a single quit message, as application shutdown might call SDL_PumpEvents().
|
|
||||||
SDL_SendQuit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1681,7 +1681,7 @@ static void Wayland_VideoCleanup(SDL_VideoDevice *_this)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Wayland_VideoReconnect(SDL_VideoDevice *_this)
|
static bool Wayland_VideoReconnect(SDL_VideoDevice *_this)
|
||||||
{
|
{
|
||||||
#if 0 // TODO RECONNECT: Uncomment all when https://invent.kde.org/plasma/kwin/-/wikis/Restarting is completed
|
#if 0 // TODO RECONNECT: Uncomment all when https://invent.kde.org/plasma/kwin/-/wikis/Restarting is completed
|
||||||
SDL_VideoData *data = _this->internal;
|
SDL_VideoData *data = _this->internal;
|
||||||
@@ -1728,6 +1728,33 @@ bool Wayland_VideoReconnect(SDL_VideoDevice *_this)
|
|||||||
#endif // 0
|
#endif // 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Wayland_HandleDisplayDisconnected(SDL_VideoDevice *_this)
|
||||||
|
{
|
||||||
|
SDL_VideoData *video_data = _this->internal;
|
||||||
|
|
||||||
|
/* Something has failed with the Wayland connection -- for example,
|
||||||
|
* the compositor may have shut down and closed its end of the socket,
|
||||||
|
* or there is a library-specific error.
|
||||||
|
*
|
||||||
|
* Try to recover once, then quit.
|
||||||
|
*/
|
||||||
|
if (video_data->display_disconnected) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Wayland_VideoReconnect(_this)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
video_data->display_disconnected = true;
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Wayland display connection closed by server (fatal)");
|
||||||
|
|
||||||
|
// Only send a single quit message, as application shutdown might call SDL_PumpEvents().
|
||||||
|
SDL_SendQuit();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Wayland_VideoQuit(SDL_VideoDevice *_this)
|
void Wayland_VideoQuit(SDL_VideoDevice *_this)
|
||||||
{
|
{
|
||||||
Wayland_VideoCleanup(_this);
|
Wayland_VideoCleanup(_this);
|
||||||
|
|||||||
@@ -48,9 +48,7 @@ typedef struct
|
|||||||
|
|
||||||
struct SDL_VideoData
|
struct SDL_VideoData
|
||||||
{
|
{
|
||||||
bool initializing;
|
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
int display_disconnected;
|
|
||||||
struct wl_registry *registry;
|
struct wl_registry *registry;
|
||||||
struct wl_compositor *compositor;
|
struct wl_compositor *compositor;
|
||||||
struct wl_shm *shm;
|
struct wl_shm *shm;
|
||||||
@@ -99,6 +97,8 @@ struct SDL_VideoData
|
|||||||
int output_count;
|
int output_count;
|
||||||
int output_max;
|
int output_max;
|
||||||
|
|
||||||
|
bool initializing;
|
||||||
|
bool display_disconnected;
|
||||||
bool display_externally_owned;
|
bool display_externally_owned;
|
||||||
bool scale_to_display_enabled;
|
bool scale_to_display_enabled;
|
||||||
};
|
};
|
||||||
@@ -140,6 +140,6 @@ struct wl_event_queue *Wayland_DisplayCreateQueue(struct wl_display *display, co
|
|||||||
|
|
||||||
extern bool Wayland_LoadLibdecor(SDL_VideoData *data, bool ignore_xdg);
|
extern bool Wayland_LoadLibdecor(SDL_VideoData *data, bool ignore_xdg);
|
||||||
|
|
||||||
extern bool Wayland_VideoReconnect(SDL_VideoDevice *_this);
|
extern bool Wayland_HandleDisplayDisconnected(SDL_VideoDevice *_this);
|
||||||
|
|
||||||
#endif // SDL_waylandvideo_h_
|
#endif // SDL_waylandvideo_h_
|
||||||
|
|||||||
@@ -2036,8 +2036,16 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
|||||||
if (data->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_LIBDECOR) {
|
if (data->shell_surface_type == WAYLAND_SHELL_SURFACE_TYPE_LIBDECOR) {
|
||||||
if (data->shell_surface.libdecor.frame) {
|
if (data->shell_surface.libdecor.frame) {
|
||||||
while (data->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) {
|
while (data->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) {
|
||||||
libdecor_dispatch(c->shell.libdecor, -1);
|
if (libdecor_dispatch(c->shell.libdecor, -1) < 0) {
|
||||||
WAYLAND_wl_display_dispatch_pending(c->display);
|
if (!Wayland_HandleDisplayDisconnected(_this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (WAYLAND_wl_display_dispatch_pending(c->display) < 0) {
|
||||||
|
if (!Wayland_HandleDisplayDisconnected(_this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -2050,7 +2058,11 @@ void Wayland_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
|||||||
wl_surface_commit(data->surface);
|
wl_surface_commit(data->surface);
|
||||||
if (data->shell_surface.xdg.surface) {
|
if (data->shell_surface.xdg.surface) {
|
||||||
while (data->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) {
|
while (data->shell_surface_status == WAYLAND_SHELL_SURFACE_STATUS_WAITING_FOR_CONFIGURE) {
|
||||||
WAYLAND_wl_display_dispatch(c->display);
|
if (WAYLAND_wl_display_dispatch(c->display) < 0) {
|
||||||
|
if (!Wayland_HandleDisplayDisconnected(_this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user