@@ -82,53 +82,125 @@ static const unsigned long retroarch_icon_data[] = {
82
82
0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000 ,0x00000000
83
83
};
84
84
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
+ bool has_size ;
114
+ bool has_window_state ;
115
+ } wayland_configuration_t ;
116
+
117
+ void xdg_toplevel_handle_configure (void * data ,
118
+ struct xdg_toplevel * xdg_toplevel ,
87
119
int32_t width , int32_t height , struct wl_array * states )
88
120
{
121
+ gfx_ctx_wayland_data_t * wl = (gfx_ctx_wayland_data_t * )data ;
89
122
const uint32_t * state ;
90
- bool floating = true;
91
123
92
- wl -> fullscreen = false;
93
- wl -> maximized = false;
124
+ wl -> pending_configuration = (wayland_configuration_t * )calloc (1 , sizeof (wayland_configuration_t ));
125
+ wayland_configuration_t * conf = wl -> pending_configuration ;
126
+
127
+ conf -> has_window_state = true;
128
+
129
+ conf -> floating = true;
94
130
95
131
WL_ARRAY_FOR_EACH (state , states , const uint32_t * )
96
132
{
97
133
switch (* state )
98
134
{
99
135
case XDG_TOPLEVEL_STATE_FULLSCREEN :
100
- wl -> fullscreen = true;
101
- floating = false;
136
+ conf -> fullscreen = true;
137
+ conf -> floating = false;
102
138
break ;
103
139
case XDG_TOPLEVEL_STATE_MAXIMIZED :
104
- wl -> maximized = true;
140
+ conf -> maximized = true;
105
141
/* fall-through */
106
142
case XDG_TOPLEVEL_STATE_TILED_LEFT :
107
143
case XDG_TOPLEVEL_STATE_TILED_RIGHT :
108
144
case XDG_TOPLEVEL_STATE_TILED_TOP :
109
145
case XDG_TOPLEVEL_STATE_TILED_BOTTOM :
110
- floating = false;
146
+ conf -> floating = false;
111
147
break ;
112
148
case XDG_TOPLEVEL_STATE_RESIZING :
113
- wl -> resize = true;
149
+ conf -> resizing = true;
114
150
break ;
115
151
case XDG_TOPLEVEL_STATE_ACTIVATED :
116
- wl -> activated = true;
152
+ conf -> activated = true;
117
153
break ;
118
154
}
119
155
}
120
156
121
- if (width == 0 || height == 0 )
157
+ conf -> has_size = true;
158
+ conf -> width = width ;
159
+ conf -> height = height ;
160
+ }
161
+
162
+ void xdg_toplevel_handle_close (void * data ,
163
+ struct xdg_toplevel * xdg_toplevel )
164
+ {
165
+ frontend_driver_set_signal_handler_state (1 );
166
+ }
167
+
168
+ static struct xdg_toplevel_listener xdg_toplevel_listener = {
169
+ .configure = xdg_toplevel_handle_configure ,
170
+ .close = xdg_toplevel_handle_close ,
171
+ };
172
+
173
+ static void xdg_surface_handle_configure (void * data ,
174
+ struct xdg_surface * xdg_surface , uint32_t serial )
175
+ {
176
+ gfx_ctx_wayland_data_t * wl = (gfx_ctx_wayland_data_t * )data ;
177
+ bool floating = true;
178
+ wayland_configuration_t * conf ;
179
+
180
+ conf = wl -> pending_configuration ;
181
+ wl -> pending_configuration = NULL ;
182
+
183
+ if (conf == NULL )
184
+ conf = (wayland_configuration_t * )calloc (1 , sizeof (wayland_configuration_t ));
185
+
186
+ if (conf -> has_window_state ) {
187
+ wl -> fullscreen = conf -> fullscreen ;
188
+ wl -> maximized = conf -> maximized ;
189
+ wl -> activated = conf -> activated ;
190
+ floating = conf -> floating ;
191
+ }
192
+
193
+ if (conf -> width == 0 || conf -> height == 0 )
122
194
{
123
- width = wl -> floating_width ;
124
- height = wl -> floating_height ;
195
+ conf -> width = wl -> floating_width ;
196
+ conf -> height = wl -> floating_height ;
125
197
}
126
198
127
- if ( (width > 0 )
128
- && (height > 0 ))
199
+ if ( (conf -> width > 0 )
200
+ && (conf -> height > 0 ))
129
201
{
130
- wl -> width = width ;
131
- wl -> height = height ;
202
+ wl -> width = conf -> width ;
203
+ wl -> height = conf -> height ;
132
204
wl -> buffer_width = wl -> fractional_scale ?
133
205
FRACTIONAL_SCALE_MULT (wl -> width , wl -> fractional_scale_num ) : wl -> width * wl -> buffer_scale ;
134
206
wl -> buffer_height = wl -> fractional_scale ?
@@ -138,28 +210,38 @@ void xdg_toplevel_handle_configure_common(gfx_ctx_wayland_data_t *wl,
138
210
{
139
211
/* Stretch old buffer to fill new size, commit/roundtrip to apply */
140
212
wp_viewport_set_destination (wl -> viewport , wl -> width , wl -> height );
141
- wl_surface_commit (wl -> surface );
142
213
}
143
214
}
144
215
145
216
if (floating )
146
217
{
147
- wl -> floating_width = width ;
148
- wl -> floating_height = height ;
218
+ wl -> floating_width = conf -> width ;
219
+ wl -> floating_height = conf -> height ;
149
220
}
150
- }
151
221
152
- void xdg_toplevel_handle_close (void * data ,
153
- struct xdg_toplevel * xdg_toplevel )
154
- {
155
- frontend_driver_set_signal_handler_state (1 );
222
+ if (wl -> driver_configure_handler != NULL )
223
+ wl -> driver_configure_handler (wl );
224
+ xdg_surface_ack_configure (xdg_surface , serial );
225
+
226
+ wl_surface_commit (wl -> surface );
227
+
228
+ if (conf != NULL )
229
+ free (conf );
230
+
231
+ wl -> configured = false;
156
232
}
157
233
234
+ static struct xdg_surface_listener xdg_surface_listener = {
235
+ .configure = xdg_surface_handle_configure ,
236
+ };
237
+
158
238
#ifdef HAVE_LIBDECOR_H
159
- void libdecor_frame_handle_configure_common (struct libdecor_frame * frame ,
239
+ void libdecor_frame_handle_configure (struct libdecor_frame * frame ,
160
240
struct libdecor_configuration * configuration ,
161
- gfx_ctx_wayland_data_t * wl )
241
+ void * data )
162
242
{
243
+ gfx_ctx_wayland_data_t * wl = (gfx_ctx_wayland_data_t * )data ;
244
+
163
245
int width = 0 , height = 0 ;
164
246
struct libdecor_state * state = NULL ;
165
247
enum libdecor_window_state window_state ;
@@ -210,7 +292,6 @@ void libdecor_frame_handle_configure_common(struct libdecor_frame *frame,
210
292
{
211
293
/* Stretch old buffer to fill new size, commit/roundtrip to apply */
212
294
wp_viewport_set_destination (wl -> viewport , wl -> width , wl -> height );
213
- wl_surface_commit (wl -> surface );
214
295
}
215
296
}
216
297
@@ -223,6 +304,13 @@ void libdecor_frame_handle_configure_common(struct libdecor_frame *frame,
223
304
wl -> floating_width = width ;
224
305
wl -> floating_height = height ;
225
306
}
307
+
308
+ if (wl -> driver_configure_handler != NULL )
309
+ wl -> driver_configure_handler (wl );
310
+
311
+ wl_surface_commit (wl -> surface );
312
+
313
+ wl -> configured = false;
226
314
}
227
315
228
316
void libdecor_frame_handle_close (struct libdecor_frame * frame ,
@@ -231,7 +319,17 @@ void libdecor_frame_handle_close(struct libdecor_frame *frame,
231
319
frontend_driver_set_signal_handler_state (1 );
232
320
}
233
321
void libdecor_frame_handle_commit (struct libdecor_frame * frame ,
234
- void * data ) { }
322
+ void * data )
323
+ {
324
+ gfx_ctx_wayland_data_t * wl = (gfx_ctx_wayland_data_t * )data ;
325
+ wl_surface_commit (wl -> surface );
326
+ }
327
+
328
+ static struct libdecor_frame_interface libdecor_frame_interface = {
329
+ .configure = libdecor_frame_handle_configure ,
330
+ .close = libdecor_frame_handle_close ,
331
+ .commit = libdecor_frame_handle_commit ,
332
+ };
235
333
#endif
236
334
237
335
void gfx_ctx_wl_get_video_size_common (void * data ,
@@ -662,7 +760,7 @@ static bool wl_draw_splash_screen(gfx_ctx_wayland_data_t *wl)
662
760
}
663
761
664
762
bool gfx_ctx_wl_init_common (
665
- const toplevel_listener_t * toplevel_listener , gfx_ctx_wayland_data_t * * wwl )
763
+ const driver_configure_handler_t driver_configure_handler , gfx_ctx_wayland_data_t * * wwl )
666
764
{
667
765
int i ;
668
766
gfx_ctx_wayland_data_t * wl ;
@@ -802,7 +900,7 @@ bool gfx_ctx_wl_init_common(
802
900
{
803
901
wl -> libdecor_context = wl -> libdecor_new (wl -> input .dpy , & libdecor_interface );
804
902
805
- wl -> libdecor_frame = wl -> libdecor_decorate (wl -> libdecor_context , wl -> surface , & toplevel_listener -> libdecor_frame_interface , wl );
903
+ wl -> libdecor_frame = wl -> libdecor_decorate (wl -> libdecor_context , wl -> surface , & libdecor_frame_interface , wl );
806
904
if (!wl -> libdecor_frame )
807
905
{
808
906
RARCH_ERR ("[Wayland]: Failed to create libdecor frame\n" );
@@ -814,7 +912,6 @@ bool gfx_ctx_wl_init_common(
814
912
wl -> libdecor_frame_map (wl -> libdecor_frame );
815
913
816
914
/* Waiting for libdecor to be configured before starting to draw */
817
- wl_surface_commit (wl -> surface );
818
915
wl -> configured = true;
819
916
820
917
while (wl -> configured )
@@ -832,8 +929,10 @@ bool gfx_ctx_wl_init_common(
832
929
wl -> xdg_surface = xdg_wm_base_get_xdg_surface (wl -> xdg_shell , wl -> surface );
833
930
xdg_surface_add_listener (wl -> xdg_surface , & xdg_surface_listener , wl );
834
931
932
+ wl -> driver_configure_handler = driver_configure_handler ;
933
+
835
934
wl -> xdg_toplevel = xdg_surface_get_toplevel (wl -> xdg_surface );
836
- xdg_toplevel_add_listener (wl -> xdg_toplevel , & toplevel_listener -> xdg_toplevel_listener , wl );
935
+ xdg_toplevel_add_listener (wl -> xdg_toplevel , & xdg_toplevel_listener , wl );
837
936
838
937
xdg_toplevel_set_app_id (wl -> xdg_toplevel , WAYLAND_APP_ID );
839
938
xdg_toplevel_set_title (wl -> xdg_toplevel , WINDOW_TITLE );
@@ -880,9 +979,6 @@ bool gfx_ctx_wl_init_common(
880
979
}
881
980
}
882
981
883
- // Ignore configure events until splash screen has been replaced
884
- wl -> ignore_configuration = true;
885
-
886
982
wl -> input .fd = wl_display_get_fd (wl -> input .dpy );
887
983
888
984
wl -> input .keyboard_focus = true;
@@ -946,6 +1042,8 @@ bool gfx_ctx_wl_set_video_mode_common_size(gfx_ctx_wayland_data_t *wl,
946
1042
}
947
1043
#endif
948
1044
1045
+ wl_surface_commit (wl -> surface );
1046
+
949
1047
return true;
950
1048
}
951
1049
@@ -1089,28 +1187,7 @@ static void shm_buffer_handle_release(void *data,
1089
1187
free (buffer );
1090
1188
}
1091
1189
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
-
1108
1190
const struct wl_buffer_listener shm_buffer_listener = {
1109
- shm_buffer_handle_release ,
1191
+ . release = shm_buffer_handle_release ,
1110
1192
};
1111
1193
1112
- #ifdef HAVE_LIBDECOR_H
1113
- const struct libdecor_interface libdecor_interface = {
1114
- .error = libdecor_handle_error ,
1115
- };
1116
- #endif
0 commit comments