Skip to content

Commit 2960357

Browse files
committed
wayland: Dedupe wayland GL/VK configure code again
Configurations of xdg_toplevels are pending until acked on xdg_surface configure. The vulkan backend doesn't need to take additional actions on configure.
1 parent ae79514 commit 2960357

File tree

6 files changed

+135
-204
lines changed

6 files changed

+135
-204
lines changed

gfx/common/wayland_common.c

Lines changed: 121 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -82,53 +82,117 @@ static const unsigned long retroarch_icon_data[] = {
8282
0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000
8383
};
8484

85-
void xdg_toplevel_handle_configure_common(gfx_ctx_wayland_data_t *wl,
86-
void *toplevel,
85+
typedef struct shm_buffer
86+
{
87+
struct wl_buffer *wl_buffer;
88+
void *data;
89+
size_t data_size;
90+
} shm_buffer_t;
91+
92+
#ifdef HAVE_LIBDECOR_H
93+
static void libdecor_handle_error(struct libdecor *context,
94+
enum libdecor_error error, const char *message)
95+
{
96+
RARCH_ERR("[Wayland]: libdecor Caught error (%d): %s\n", error, message);
97+
}
98+
99+
const struct libdecor_interface libdecor_interface = {
100+
.error = libdecor_handle_error,
101+
};
102+
#endif
103+
104+
typedef struct wayland_configuration
105+
{
106+
unsigned width;
107+
unsigned height;
108+
bool fullscreen;
109+
bool maximized;
110+
bool floating;
111+
bool resizing;
112+
bool activated;
113+
} wayland_configuration_t;
114+
115+
void xdg_toplevel_handle_configure(void *data,
116+
struct xdg_toplevel *xdg_toplevel,
87117
int32_t width, int32_t height, struct wl_array *states)
88118
{
119+
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
89120
const uint32_t *state;
90-
bool floating = true;
91121

92-
wl->fullscreen = false;
93-
wl->maximized = false;
122+
wl->pending_configuration = (wayland_configuration_t*)calloc(1, sizeof(wayland_configuration_t));
123+
wayland_configuration_t *conf = wl->pending_configuration;
124+
125+
conf->floating = true;
94126

95127
WL_ARRAY_FOR_EACH(state, states, const uint32_t*)
96128
{
97129
switch (*state)
98130
{
99131
case XDG_TOPLEVEL_STATE_FULLSCREEN:
100-
wl->fullscreen = true;
101-
floating = false;
132+
conf->fullscreen = true;
133+
conf->floating = false;
102134
break;
103135
case XDG_TOPLEVEL_STATE_MAXIMIZED:
104-
wl->maximized = true;
136+
conf->maximized = true;
105137
/* fall-through */
106138
case XDG_TOPLEVEL_STATE_TILED_LEFT:
107139
case XDG_TOPLEVEL_STATE_TILED_RIGHT:
108140
case XDG_TOPLEVEL_STATE_TILED_TOP:
109141
case XDG_TOPLEVEL_STATE_TILED_BOTTOM:
110-
floating = false;
142+
conf->floating = false;
111143
break;
112144
case XDG_TOPLEVEL_STATE_RESIZING:
113-
wl->resize = true;
145+
conf->resizing = true;
114146
break;
115147
case XDG_TOPLEVEL_STATE_ACTIVATED:
116-
wl->activated = true;
148+
conf->activated = true;
117149
break;
118150
}
119151
}
120152

121-
if (width == 0 || height == 0)
153+
conf->width = width;
154+
conf->height = height;
155+
}
156+
157+
void xdg_toplevel_handle_close(void *data,
158+
struct xdg_toplevel *xdg_toplevel);
159+
160+
static struct xdg_toplevel_listener xdg_toplevel_listener = {
161+
.configure = xdg_toplevel_handle_configure,
162+
.close = xdg_toplevel_handle_close,
163+
};
164+
165+
static void xdg_surface_handle_configure(void *data,
166+
struct xdg_surface *xdg_surface, uint32_t serial)
167+
{
168+
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
169+
wayland_configuration_t *conf;
170+
171+
conf = wl->pending_configuration;
172+
wl->pending_configuration = NULL;
173+
174+
if (conf == NULL)
175+
conf = (wayland_configuration_t*)calloc(1, sizeof(wayland_configuration_t));
176+
// TODO: Set defaults for wayland_configuration_t!
177+
178+
bool floating = conf->floating;
179+
180+
wl->fullscreen = conf->fullscreen;
181+
wl->maximized = conf->maximized;
182+
wl->resize = conf->resizing;
183+
wl->activated = conf->activated;
184+
185+
if (conf->width == 0 || conf->height == 0)
122186
{
123-
width = wl->floating_width;
124-
height = wl->floating_height;
187+
conf->width = wl->floating_width;
188+
conf->height = wl->floating_height;
125189
}
126190

127-
if ( (width > 0)
128-
&& (height > 0))
191+
if ( (conf->width > 0)
192+
&& (conf->height > 0))
129193
{
130-
wl->width = width;
131-
wl->height = height;
194+
wl->width = conf->width;
195+
wl->height = conf->height;
132196
wl->buffer_width = wl->fractional_scale ?
133197
FRACTIONAL_SCALE_MULT(wl->width, wl->fractional_scale_num) : wl->width * wl->buffer_scale;
134198
wl->buffer_height = wl->fractional_scale ?
@@ -144,22 +208,39 @@ void xdg_toplevel_handle_configure_common(gfx_ctx_wayland_data_t *wl,
144208

145209
if (floating)
146210
{
147-
wl->floating_width = width;
148-
wl->floating_height = height;
211+
wl->floating_width = conf->width;
212+
wl->floating_height = conf->height;
149213
}
214+
215+
if (wl->driver_configure_handler != NULL)
216+
wl->driver_configure_handler(wl);
217+
xdg_surface_ack_configure(xdg_surface, serial);
218+
219+
wl_surface_commit(wl->surface);
220+
221+
if (conf != NULL)
222+
free(conf);
223+
224+
wl->configured = false;
150225
}
151226

227+
static struct xdg_surface_listener xdg_surface_listener = {
228+
.configure = xdg_surface_handle_configure
229+
};
230+
152231
void xdg_toplevel_handle_close(void *data,
153232
struct xdg_toplevel *xdg_toplevel)
154233
{
155234
frontend_driver_set_signal_handler_state(1);
156235
}
157236

158237
#ifdef HAVE_LIBDECOR_H
159-
void libdecor_frame_handle_configure_common(struct libdecor_frame *frame,
238+
void libdecor_frame_handle_configure(struct libdecor_frame *frame,
160239
struct libdecor_configuration *configuration,
161-
gfx_ctx_wayland_data_t *wl)
240+
void *data)
162241
{
242+
gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data;
243+
163244
int width = 0, height = 0;
164245
struct libdecor_state *state = NULL;
165246
enum libdecor_window_state window_state;
@@ -223,6 +304,11 @@ void libdecor_frame_handle_configure_common(struct libdecor_frame *frame,
223304
wl->floating_width = width;
224305
wl->floating_height = height;
225306
}
307+
308+
if (wl->driver_configure_handler != NULL)
309+
wl->driver_configure_handler(wl);
310+
311+
wl->configured = false;
226312
}
227313

228314
void libdecor_frame_handle_close(struct libdecor_frame *frame,
@@ -232,6 +318,12 @@ void libdecor_frame_handle_close(struct libdecor_frame *frame,
232318
}
233319
void libdecor_frame_handle_commit(struct libdecor_frame *frame,
234320
void *data) { }
321+
322+
static struct libdecor_frame_interface libdecor_frame_interface = {
323+
.configure = libdecor_frame_handle_configure,
324+
.close = libdecor_frame_handle_close,
325+
.commit = libdecor_frame_handle_commit,
326+
};
235327
#endif
236328

237329
void gfx_ctx_wl_get_video_size_common(void *data,
@@ -662,7 +754,7 @@ static bool wl_draw_splash_screen(gfx_ctx_wayland_data_t *wl)
662754
}
663755

664756
bool gfx_ctx_wl_init_common(
665-
const toplevel_listener_t *toplevel_listener, gfx_ctx_wayland_data_t **wwl)
757+
const driver_configure_handler_t driver_configure_handler, gfx_ctx_wayland_data_t **wwl)
666758
{
667759
int i;
668760
gfx_ctx_wayland_data_t *wl;
@@ -802,7 +894,7 @@ bool gfx_ctx_wl_init_common(
802894
{
803895
wl->libdecor_context = wl->libdecor_new(wl->input.dpy, &libdecor_interface);
804896

805-
wl->libdecor_frame = wl->libdecor_decorate(wl->libdecor_context, wl->surface, &toplevel_listener->libdecor_frame_interface, wl);
897+
wl->libdecor_frame = wl->libdecor_decorate(wl->libdecor_context, wl->surface, &libdecor_frame_interface, wl);
806898
if (!wl->libdecor_frame)
807899
{
808900
RARCH_ERR("[Wayland]: Failed to create libdecor frame\n");
@@ -832,8 +924,10 @@ bool gfx_ctx_wl_init_common(
832924
wl->xdg_surface = xdg_wm_base_get_xdg_surface(wl->xdg_shell, wl->surface);
833925
xdg_surface_add_listener(wl->xdg_surface, &xdg_surface_listener, wl);
834926

927+
wl->driver_configure_handler = driver_configure_handler;
928+
835929
wl->xdg_toplevel = xdg_surface_get_toplevel(wl->xdg_surface);
836-
xdg_toplevel_add_listener(wl->xdg_toplevel, &toplevel_listener->xdg_toplevel_listener, wl);
930+
xdg_toplevel_add_listener(wl->xdg_toplevel, &xdg_toplevel_listener, wl);
837931

838932
xdg_toplevel_set_app_id(wl->xdg_toplevel, WAYLAND_APP_ID);
839933
xdg_toplevel_set_title(wl->xdg_toplevel, WINDOW_TITLE);
@@ -880,9 +974,6 @@ bool gfx_ctx_wl_init_common(
880974
}
881975
}
882976

883-
// Ignore configure events until splash screen has been replaced
884-
wl->ignore_configuration = true;
885-
886977
wl->input.fd = wl_display_get_fd(wl->input.dpy);
887978

888979
wl->input.keyboard_focus = true;
@@ -946,6 +1037,8 @@ bool gfx_ctx_wl_set_video_mode_common_size(gfx_ctx_wayland_data_t *wl,
9461037
}
9471038
#endif
9481039

1040+
wl_surface_commit(wl->surface);
1041+
9491042
return true;
9501043
}
9511044

@@ -1089,28 +1182,7 @@ static void shm_buffer_handle_release(void *data,
10891182
free(buffer);
10901183
}
10911184

1092-
#if 0
1093-
static void xdg_surface_handle_configure(void *data,
1094-
struct xdg_surface *surface, uint32_t serial)
1095-
{
1096-
xdg_surface_ack_configure(surface, serial);
1097-
}
1098-
#endif
1099-
1100-
#ifdef HAVE_LIBDECOR_H
1101-
static void libdecor_handle_error(struct libdecor *context,
1102-
enum libdecor_error error, const char *message)
1103-
{
1104-
RARCH_ERR("[Wayland]: libdecor Caught error (%d): %s\n", error, message);
1105-
}
1106-
#endif
1107-
11081185
const struct wl_buffer_listener shm_buffer_listener = {
11091186
shm_buffer_handle_release,
11101187
};
11111188

1112-
#ifdef HAVE_LIBDECOR_H
1113-
const struct libdecor_interface libdecor_interface = {
1114-
.error = libdecor_handle_error,
1115-
};
1116-
#endif

gfx/common/wayland_common.h

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,10 @@
1515

1616
#pragma once
1717

18-
#ifdef HAVE_LIBDECOR_H
19-
#include <libdecor.h>
20-
#endif
21-
2218
#include "../../input/common/wayland_common.h"
2319

2420
#define WAYLAND_APP_ID "com.libretro.RetroArch"
2521

26-
typedef struct toplevel_listener
27-
{
28-
#ifdef HAVE_LIBDECOR_H
29-
struct libdecor_frame_interface libdecor_frame_interface;
30-
#endif
31-
struct xdg_toplevel_listener xdg_toplevel_listener;
32-
} toplevel_listener_t;
33-
34-
typedef struct shm_buffer
35-
{
36-
struct wl_buffer *wl_buffer;
37-
void *data;
38-
size_t data_size;
39-
} shm_buffer_t;
40-
41-
void xdg_toplevel_handle_configure_common(gfx_ctx_wayland_data_t *wl, void *toplevel,
42-
int32_t width, int32_t height, struct wl_array *states);
43-
44-
void xdg_toplevel_handle_close(void *data,
45-
struct xdg_toplevel *xdg_toplevel);
46-
47-
#ifdef HAVE_LIBDECOR_H
48-
void libdecor_frame_handle_configure_common(struct libdecor_frame *frame,
49-
struct libdecor_configuration *configuration, gfx_ctx_wayland_data_t *wl);
50-
51-
void libdecor_frame_handle_close(struct libdecor_frame *frame,
52-
void *data);
53-
54-
void libdecor_frame_handle_commit(struct libdecor_frame *frame,
55-
void *data);
56-
#endif
57-
5822
void gfx_ctx_wl_get_video_size_common(void *data, unsigned *width,
5923
unsigned *height);
6024

@@ -66,7 +30,7 @@ bool gfx_ctx_wl_get_metrics_common(void *data,
6630
enum display_metric_types type, float *value);
6731

6832
bool gfx_ctx_wl_init_common(
69-
const toplevel_listener_t *toplevel_listener,
33+
const driver_configure_handler_t driver_configure_handler,
7034
gfx_ctx_wayland_data_t **wl);
7135

7236
bool gfx_ctx_wl_set_video_mode_common_size(gfx_ctx_wayland_data_t *wl,
@@ -89,6 +53,3 @@ void gfx_ctx_wl_check_window_common(gfx_ctx_wayland_data_t *wl,
8953
void (*get_video_size)(void*, unsigned*, unsigned*), bool *quit,
9054
bool *resize, unsigned *width, unsigned *height);
9155

92-
#ifdef HAVE_LIBDECOR_H
93-
extern const struct libdecor_interface libdecor_interface;
94-
#endif

0 commit comments

Comments
 (0)