wayland: Cleanup work to aid reconnect support

Co-authored-by: David Edmundson <kde@davidedmundson.co.uk>
This commit is contained in:
Ethan Lee 2022-10-29 22:34:05 -04:00
parent f6b1e028ab
commit 9c8b1fd8b6
7 changed files with 167 additions and 36 deletions

View File

@ -266,6 +266,30 @@ SDL_GetMouseFocus(void)
return mouse->focus;
}
/* TODO RECONNECT: Hello from the Wayland video driver!
* This was once removed from SDL, but it's been added back in comment form
* because we will need it when Wayland adds compositor reconnect support.
* If you need this before we do, great! Otherwise, leave this alone, we'll
* uncomment it at the right time.
* -flibit
*/
#if 0
void
SDL_ResetMouse(void)
{
SDL_Mouse *mouse = SDL_GetMouse();
Uint32 buttonState = GetButtonState(mouse, SDL_FALSE);
int i;
for (i = 1; i <= sizeof(buttonState)*8; ++i) {
if (buttonState & SDL_BUTTON(i)) {
SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, i);
}
}
SDL_assert(GetButtonState(mouse, SDL_FALSE) == 0);
}
#endif /* 0 */
void
SDL_SetMouseFocus(SDL_Window * window)
{

View File

@ -164,6 +164,11 @@ extern int SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, float x,
/* Warp the mouse within the window, potentially overriding relative mode */
extern void SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_relative_mode);
/* TODO RECONNECT: Set mouse state to "zero" */
#if 0
extern void SDL_ResetMouse(void);
#endif /* 0 */
/* Shutdown the mouse subsystem */
extern void SDL_MouseQuit(void);

View File

@ -102,6 +102,7 @@ void SDL_WAYLAND_UnloadSymbols(void);
#define wl_proxy_get_tag (*WAYLAND_wl_proxy_get_tag)
#define wl_proxy_marshal_flags (*WAYLAND_wl_proxy_marshal_flags)
#define wl_proxy_marshal_array_flags (*WAYLAND_wl_proxy_marshal_array_flags)
#define wl_display_reconnect (*WAYLAND_wl_display_reconnect)
#define wl_seat_interface (*WAYLAND_wl_seat_interface)
#define wl_surface_interface (*WAYLAND_wl_surface_interface)

View File

@ -420,11 +420,18 @@ Wayland_PumpEvents(_THIS)
if (err < 0 && !d->display_disconnected) {
/* 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. No recovery is possible. */
d->display_disconnected = 1;
/* Only send a single quit message, as application shutdown might call
* SDL_PumpEvents */
SDL_SendQuit();
* or there is a library-specific error.
*
* Try to recover once, then quit.
*/
if (!Wayland_VideoReconnect(_this)) {
d->display_disconnected = 1;
/* Only send a single quit message, as application shutdown might call
* SDL_PumpEvents
*/
SDL_SendQuit();
}
}
}

View File

@ -86,6 +86,12 @@ SDL_WAYLAND_SYM(struct wl_proxy*, wl_proxy_marshal_flags, (struct wl_proxy *prox
SDL_WAYLAND_SYM(struct wl_proxy*, wl_proxy_marshal_array_flags, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, uint32_t flags, union wl_argument *args))
#endif
#if 0 /* TODO RECONNECT: See waylandvideo.c for more information! */
#if SDL_WAYLAND_CHECK_VERSION(broken, on, purpose)
SDL_WAYLAND_SYM(int, wl_display_reconnect, (struct wl_display*));
#endif
#endif /* 0 */
SDL_WAYLAND_INTERFACE(wl_seat_interface)
SDL_WAYLAND_INTERFACE(wl_surface_interface)
SDL_WAYLAND_INTERFACE(wl_shm_pool_interface)

View File

@ -1028,7 +1028,7 @@ Wayland_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float
}
void
Wayland_VideoQuit(_THIS)
Wayland_VideoCleanup(_THIS)
{
SDL_VideoData *data = _this->driverdata;
int i, j;
@ -1036,7 +1036,7 @@ Wayland_VideoQuit(_THIS)
Wayland_QuitWin(data);
Wayland_FiniMouse(data);
for (i = 0; i < _this->num_displays; ++i) {
for (i = _this->num_displays - 1; i >= 0; --i) {
SDL_VideoDisplay *display = &_this->displays[i];
if (((SDL_WaylandOutputData*)display->driverdata)->xdg_output) {
@ -1051,54 +1051,158 @@ Wayland_VideoQuit(_THIS)
display->display_modes[j].driverdata = NULL;
}
display->desktop_mode.driverdata = NULL;
SDL_DelVideoDisplay(i);
}
Wayland_display_destroy_input(data);
Wayland_display_destroy_pointer_constraints(data);
Wayland_display_destroy_relative_pointer_manager(data);
if (data->activation_manager)
if (data->activation_manager) {
xdg_activation_v1_destroy(data->activation_manager);
data->activation_manager = NULL;
}
if (data->idle_inhibit_manager)
if (data->idle_inhibit_manager) {
zwp_idle_inhibit_manager_v1_destroy(data->idle_inhibit_manager);
data->idle_inhibit_manager = NULL;
}
if (data->key_inhibitor_manager)
if (data->key_inhibitor_manager) {
zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(data->key_inhibitor_manager);
data->key_inhibitor_manager = NULL;
}
Wayland_QuitKeyboard(_this);
if (data->text_input_manager)
if (data->text_input_manager) {
zwp_text_input_manager_v3_destroy(data->text_input_manager);
data->text_input_manager = NULL;
}
if (data->xkb_context) {
WAYLAND_xkb_context_unref(data->xkb_context);
data->xkb_context = NULL;
}
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
if (data->windowmanager)
if (data->windowmanager) {
qt_windowmanager_destroy(data->windowmanager);
data->windowmanager = NULL;
}
if (data->surface_extension)
if (data->surface_extension) {
qt_surface_extension_destroy(data->surface_extension);
data->surface_extension = NULL;
}
Wayland_touch_destroy(data);
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
if (data->tablet_manager)
if (data->tablet_manager) {
zwp_tablet_manager_v2_destroy((struct zwp_tablet_manager_v2*)data->tablet_manager);
data->tablet_manager = NULL;
}
if (data->data_device_manager)
if (data->data_device_manager) {
wl_data_device_manager_destroy(data->data_device_manager);
data->data_device_manager = NULL;
}
if (data->shm)
if (data->shm) {
wl_shm_destroy(data->shm);
data->shm = NULL;
}
if (data->shell.xdg)
if (data->shell.xdg) {
xdg_wm_base_destroy(data->shell.xdg);
data->shell.xdg = NULL;
}
if (data->decoration_manager)
if (data->decoration_manager) {
zxdg_decoration_manager_v1_destroy(data->decoration_manager);
data->decoration_manager = NULL;
}
if (data->xdg_output_manager) {
zxdg_output_manager_v1_destroy(data->xdg_output_manager);
data->xdg_output_manager = NULL;
}
if (data->viewporter) {
wp_viewporter_destroy(data->viewporter);
data->viewporter = NULL;
}
if (data->primary_selection_device_manager) {
zwp_primary_selection_device_manager_v1_destroy(data->primary_selection_device_manager);
data->primary_selection_device_manager = NULL;
}
if (data->compositor) {
wl_compositor_destroy(data->compositor);
data->compositor = NULL;
}
if (data->registry) {
wl_registry_destroy(data->registry);
data->registry = NULL;
}
}
SDL_bool
Wayland_VideoReconnect(_THIS)
{
#if 0 /* TODO RECONNECT: Uncomment all when https://invent.kde.org/plasma/kwin/-/wikis/Restarting is completed */
SDL_VideoData *data = _this->driverdata;
SDL_Window *window = NULL;
SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
SDL_Window *current_window = SDL_GL_GetCurrentWindow();
Wayland_FiniMouse(data);
SDL_GL_MakeCurrent(NULL, NULL);
Wayland_VideoCleanup(_this);
SDL_ResetKeyboard();
SDL_ResetMouse();
if (WAYLAND_wl_display_reconnect(data->display) < 0) {
return SDL_FALSE;
}
Wayland_VideoInit(_this);
window = _this->windows;
while (window) {
/* We're going to cheat _just_ for a second and strip the OpenGL flag.
* The Wayland driver actually forces it in CreateWindow, and
* RecreateWindow does a bunch of unloading/loading of libGL, so just
* strip the flag so RecreateWindow doesn't mess with the GL context,
* and CreateWindow will add it right back!
* -flibit
*/
window->flags &= ~SDL_WINDOW_OPENGL;
SDL_RecreateWindow(window, window->flags);
window = window->next;
}
if (current_window && current_ctx) {
SDL_GL_MakeCurrent (current_window, current_ctx);
}
return SDL_TRUE;
#else
return SDL_FALSE;
#endif /* 0 */
}
void
Wayland_VideoQuit(_THIS)
{
SDL_VideoData *data = _this->driverdata;
Wayland_VideoCleanup(_this);
#ifdef HAVE_LIBDECOR_H
if (data->shell.libdecor) {
@ -1107,24 +1211,6 @@ Wayland_VideoQuit(_THIS)
}
#endif
if (data->xdg_output_manager) {
zxdg_output_manager_v1_destroy(data->xdg_output_manager);
}
if (data->viewporter) {
wp_viewporter_destroy(data->viewporter);
}
if (data->primary_selection_device_manager) {
zwp_primary_selection_device_manager_v1_destroy(data->primary_selection_device_manager);
}
if (data->compositor)
wl_compositor_destroy(data->compositor);
if (data->registry)
wl_registry_destroy(data->registry);
SDL_free(data->classname);
}

View File

@ -126,6 +126,8 @@ extern SDL_bool SDL_WAYLAND_own_output(struct wl_output *output);
extern SDL_bool Wayland_LoadLibdecor(SDL_VideoData *data, SDL_bool ignore_xdg);
extern SDL_bool Wayland_VideoReconnect(_THIS);
#endif /* SDL_waylandvideo_h_ */
/* vi: set ts=4 sw=4 expandtab: */