Simple Directmedia Layer

wayland: Remove kde_output_order_v1 support

This protocol is unstable and not intended for clients, and SDL now sorts the display list into a stable order and selects a primary display suitable for games on its own, so it isn't necessary.

Reverts e71e16950a5591913bd15bc8f4d04c01bf654b72

Changed files
+13 -143
src
wayland-protocols
+13 -107
src/video/wayland/SDL_waylandvideo.c
··· 49 49 #include "frog-color-management-v1-client-protocol.h" 50 50 #include "idle-inhibit-unstable-v1-client-protocol.h" 51 51 #include "input-timestamps-unstable-v1-client-protocol.h" 52 - #include "kde-output-order-v1-client-protocol.h" 53 52 #include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h" 54 53 #include "pointer-constraints-unstable-v1-client-protocol.h" 55 54 #include "primary-selection-unstable-v1-client-protocol.h" ··· 203 202 return false; 204 203 } 205 204 206 - static void Wayland_FlushOutputOrder(SDL_VideoData *vid) 207 - { 208 - SDL_WaylandConnectorName *c, *tmp; 209 - wl_list_for_each_safe (c, tmp, &vid->output_order, link) { 210 - WAYLAND_wl_list_remove(&c->link); 211 - SDL_free(c); 212 - } 213 - 214 - vid->output_order_finalized = false; 215 - } 216 - 217 - /* The order of wl_output displays exposed by KDE doesn't correspond to any priority, but KDE does provide a protocol 218 - * that tells clients the preferred order or all connected displays via an ordered list of connector name strings. 219 - */ 220 - static void handle_kde_output_order_output(void *data, struct kde_output_order_v1 *kde_output_order_v1, const char *output_name) 221 - { 222 - SDL_VideoData *vid = (SDL_VideoData *)data; 223 - 224 - // Starting a new list, flush the old. 225 - if (vid->output_order_finalized) { 226 - Wayland_FlushOutputOrder(vid); 227 - } 228 - 229 - const int len = SDL_strlen(output_name) + 1; 230 - SDL_WaylandConnectorName *node = SDL_malloc(sizeof(SDL_WaylandConnectorName) + len); 231 - SDL_strlcpy(node->wl_output_name, output_name, len); 232 - 233 - WAYLAND_wl_list_insert(vid->output_order.prev, &node->link); 234 - } 235 - 236 - static void handle_kde_output_order_done(void *data, struct kde_output_order_v1 *kde_output_order_v1) 237 - { 238 - SDL_VideoData *vid = (SDL_VideoData *)data; 239 - vid->output_order_finalized = true; 240 - } 241 - 242 - static const struct kde_output_order_v1_listener kde_output_order_listener = { 243 - handle_kde_output_order_output, 244 - handle_kde_output_order_done 245 - }; 246 - 247 205 // Sort the list of displays into a deterministic order 248 206 static int SDLCALL Wayland_DisplayPositionCompare(const void *a, const void *b) 249 207 { ··· 350 308 return best_index; 351 309 } 352 310 353 - static bool Wayland_SortOutputsByPriorityHint(SDL_VideoData *vid) 311 + static void Wayland_SortOutputsByPriorityHint(SDL_VideoData *vid) 354 312 { 355 313 const char *name_hint = SDL_GetHint(SDL_HINT_VIDEO_DISPLAY_PRIORITY); 356 314 ··· 358 316 char *saveptr; 359 317 char *str = SDL_strdup(name_hint); 360 318 SDL_DisplayData **sorted_list = SDL_malloc(sizeof(SDL_DisplayData *) * vid->output_count); 361 - int sorted_index = 0; 362 319 363 320 if (str && sorted_list) { 321 + int sorted_index = 0; 322 + 364 323 // Sort the requested displays to the front of the list. 365 324 const char *token = SDL_strtok_r(str, ",", &saveptr); 366 325 while (token) { ··· 389 348 390 349 SDL_free(str); 391 350 SDL_free(sorted_list); 392 - 393 - return true; 394 351 } 395 - 396 - return false; 397 352 } 398 353 399 354 static void Wayland_SortOutputs(SDL_VideoData *vid) 400 355 { 401 - bool have_primary = false; 402 - 403 - /* KDE provides the kde-output-order-v1 protocol, which gives us the full preferred display 404 - * ordering in the form of a list of wl_output.name strings. 405 - */ 406 - if (!WAYLAND_wl_list_empty(&vid->output_order)) { 407 - SDL_WaylandConnectorName *c; 408 - SDL_DisplayData **sorted_list = SDL_malloc(sizeof(SDL_DisplayData *) * vid->output_count); 409 - int sorted_index = 0; 410 - 411 - if (sorted_list) { 412 - // Sort the outputs by connector name. 413 - wl_list_for_each (c, &vid->output_order, link) { 414 - for (int i = 0; i < vid->output_count; ++i) { 415 - SDL_DisplayData *d = vid->output_list[i]; 416 - if (d && d->wl_output_name && SDL_strcmp(c->wl_output_name, d->wl_output_name) == 0) { 417 - sorted_list[sorted_index++] = d; 418 - vid->output_list[i] = NULL; 419 - break; 420 - } 421 - } 422 - } 423 - 424 - /* If any displays were omitted during the sort, append them to the new list. 425 - * This shouldn't happen, but better safe than sorry. 426 - */ 427 - for (int i = 0; i < vid->output_count; ++i) { 428 - if (vid->output_list[i]) { 429 - sorted_list[sorted_index++] = vid->output_list[i]; 430 - } 431 - } 432 - 433 - // Copy the sorted list to the output list. 434 - SDL_memcpy(vid->output_list, sorted_list, sizeof(SDL_DisplayData *) * vid->output_count); 435 - SDL_free(sorted_list); 356 + // Sort by position or connector name, so the order of outputs is deterministic. 357 + SDL_qsort(vid->output_list, vid->output_count, sizeof(SDL_DisplayData *), Wayland_DisplayPositionCompare); 436 358 437 - have_primary = true; 438 - } 439 - } else { 440 - // Sort by position or connector name, so the order of outputs is deterministic. 441 - SDL_qsort(vid->output_list, vid->output_count, sizeof(SDL_DisplayData *), Wayland_DisplayPositionCompare); 359 + // Find a suitable primary display and move it to the front of the list. 360 + const int primary_index = Wayland_GetPrimaryDisplay(vid); 361 + if (primary_index) { 362 + SDL_DisplayData *primary = vid->output_list[primary_index]; 363 + SDL_memmove(&vid->output_list[1], &vid->output_list[0], sizeof(SDL_DisplayData *) * primary_index); 364 + vid->output_list[0] = primary; 442 365 } 443 366 444 - // Apply the ordering hint if specified, otherwise, try to find the primary display, if no preferred order is known. 445 - if (!Wayland_SortOutputsByPriorityHint(vid) && !have_primary) { 446 - const int primary_index = Wayland_GetPrimaryDisplay(vid); 447 - if (primary_index) { 448 - SDL_DisplayData *primary = vid->output_list[primary_index]; 449 - SDL_memmove(&vid->output_list[1], &vid->output_list[0], sizeof(SDL_DisplayData *) * primary_index); 450 - vid->output_list[0] = primary; 451 - } 452 - } 367 + // Apply the ordering hint, if specified. 368 + Wayland_SortOutputsByPriorityHint(vid); 453 369 } 454 370 455 371 static void display_handle_done(void *data, struct wl_output *output); ··· 643 559 data->input = input; 644 560 data->display_externally_owned = display_is_external; 645 561 data->scale_to_display_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_SCALE_TO_DISPLAY, false); 646 - WAYLAND_wl_list_init(&data->output_order); 647 562 WAYLAND_wl_list_init(&external_window_list); 648 563 649 564 // Initialize all variables that we clean on shutdown ··· 1353 1268 d->wp_alpha_modifier_v1 = wl_registry_bind(d->registry, id, &wp_alpha_modifier_v1_interface, 1); 1354 1269 } else if (SDL_strcmp(interface, "xdg_toplevel_icon_manager_v1") == 0) { 1355 1270 d->xdg_toplevel_icon_manager_v1 = wl_registry_bind(d->registry, id, &xdg_toplevel_icon_manager_v1_interface, 1); 1356 - } else if (SDL_strcmp(interface, "kde_output_order_v1") == 0) { 1357 - d->kde_output_order = wl_registry_bind(d->registry, id, &kde_output_order_v1_interface, 1); 1358 - kde_output_order_v1_add_listener(d->kde_output_order, &kde_output_order_listener, d); 1359 1271 } else if (SDL_strcmp(interface, "frog_color_management_factory_v1") == 0) { 1360 1272 d->frog_color_management_factory_v1 = wl_registry_bind(d->registry, id, &frog_color_management_factory_v1_interface, 1); 1361 1273 } ··· 1632 1544 if (data->xdg_toplevel_icon_manager_v1) { 1633 1545 xdg_toplevel_icon_manager_v1_destroy(data->xdg_toplevel_icon_manager_v1); 1634 1546 data->xdg_toplevel_icon_manager_v1 = NULL; 1635 - } 1636 - 1637 - if (data->kde_output_order) { 1638 - Wayland_FlushOutputOrder(data); 1639 - kde_output_order_v1_destroy(data->kde_output_order); 1640 - data->kde_output_order = NULL; 1641 1547 } 1642 1548 1643 1549 if (data->frog_color_management_factory_v1) {
-3
src/video/wayland/SDL_waylandvideo.h
··· 91 91 SDL_DisplayData **output_list; 92 92 int output_count; 93 93 int output_max; 94 - struct wl_list output_order; 95 - 96 - bool output_order_finalized; 97 94 98 95 int relative_mouse_mode; 99 96 bool display_externally_owned;
-33
wayland-protocols/kde-output-order-v1.xml
··· 1 - <?xml version="1.0" encoding="UTF-8"?> 2 - <protocol name="kde_output_order_v1"> 3 - <copyright><![CDATA[ 4 - SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com> 5 - 6 - SPDX-License-Identifier: MIT-CMU 7 - ]]></copyright> 8 - 9 - <interface name="kde_output_order_v1" version="1"> 10 - <description summary="announce order of outputs"> 11 - Announce the order in which desktop environment components should be placed on outputs. 12 - The compositor will send the list of outputs when the global is bound and whenever there is a change. 13 - </description> 14 - 15 - <event name="output"> 16 - <description summary="output name"> 17 - Specifies the output identified by their wl_output.name. 18 - </description> 19 - <arg name="output_name" type="string" summary="the name of the output"/> 20 - </event> 21 - 22 - <event name="done"> 23 - <description summary="done"> 24 - Specifies that the output list is complete. On the next output event, a new list begins. 25 - </description> 26 - </event> 27 - 28 - <request name="destroy" type="destructor"> 29 - <description summary="Destroy the output order notifier."/> 30 - </request> 31 - </interface> 32 - 33 - </protocol>