From 4c2d0c422b11ac5515ad123cfe3d659d0e45722c Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sat, 19 Oct 2024 11:13:24 -0400
Subject: [PATCH] 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
---
src/video/wayland/SDL_waylandvideo.c | 120 +++-------------------
src/video/wayland/SDL_waylandvideo.h | 3 -
wayland-protocols/kde-output-order-v1.xml | 33 ------
3 files changed, 13 insertions(+), 143 deletions(-)
delete mode 100644 wayland-protocols/kde-output-order-v1.xml
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 13744a2cb2134..d93eb60b4794e 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -49,7 +49,6 @@
#include "frog-color-management-v1-client-protocol.h"
#include "idle-inhibit-unstable-v1-client-protocol.h"
#include "input-timestamps-unstable-v1-client-protocol.h"
-#include "kde-output-order-v1-client-protocol.h"
#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
#include "pointer-constraints-unstable-v1-client-protocol.h"
#include "primary-selection-unstable-v1-client-protocol.h"
@@ -203,47 +202,6 @@ static bool Wayland_GetGNOMEPrimaryDisplayCoordinates(int *x, int *y)
return false;
}
-static void Wayland_FlushOutputOrder(SDL_VideoData *vid)
-{
- SDL_WaylandConnectorName *c, *tmp;
- wl_list_for_each_safe (c, tmp, &vid->output_order, link) {
- WAYLAND_wl_list_remove(&c->link);
- SDL_free(c);
- }
-
- vid->output_order_finalized = false;
-}
-
-/* The order of wl_output displays exposed by KDE doesn't correspond to any priority, but KDE does provide a protocol
- * that tells clients the preferred order or all connected displays via an ordered list of connector name strings.
- */
-static void handle_kde_output_order_output(void *data, struct kde_output_order_v1 *kde_output_order_v1, const char *output_name)
-{
- SDL_VideoData *vid = (SDL_VideoData *)data;
-
- // Starting a new list, flush the old.
- if (vid->output_order_finalized) {
- Wayland_FlushOutputOrder(vid);
- }
-
- const int len = SDL_strlen(output_name) + 1;
- SDL_WaylandConnectorName *node = SDL_malloc(sizeof(SDL_WaylandConnectorName) + len);
- SDL_strlcpy(node->wl_output_name, output_name, len);
-
- WAYLAND_wl_list_insert(vid->output_order.prev, &node->link);
-}
-
-static void handle_kde_output_order_done(void *data, struct kde_output_order_v1 *kde_output_order_v1)
-{
- SDL_VideoData *vid = (SDL_VideoData *)data;
- vid->output_order_finalized = true;
-}
-
-static const struct kde_output_order_v1_listener kde_output_order_listener = {
- handle_kde_output_order_output,
- handle_kde_output_order_done
-};
-
// Sort the list of displays into a deterministic order
static int SDLCALL Wayland_DisplayPositionCompare(const void *a, const void *b)
{
@@ -350,7 +308,7 @@ static int Wayland_GetPrimaryDisplay(SDL_VideoData *vid)
return best_index;
}
-static bool Wayland_SortOutputsByPriorityHint(SDL_VideoData *vid)
+static void Wayland_SortOutputsByPriorityHint(SDL_VideoData *vid)
{
const char *name_hint = SDL_GetHint(SDL_HINT_VIDEO_DISPLAY_PRIORITY);
@@ -358,9 +316,10 @@ static bool Wayland_SortOutputsByPriorityHint(SDL_VideoData *vid)
char *saveptr;
char *str = SDL_strdup(name_hint);
SDL_DisplayData **sorted_list = SDL_malloc(sizeof(SDL_DisplayData *) * vid->output_count);
- int sorted_index = 0;
if (str && sorted_list) {
+ int sorted_index = 0;
+
// Sort the requested displays to the front of the list.
const char *token = SDL_strtok_r(str, ",", &saveptr);
while (token) {
@@ -389,67 +348,24 @@ static bool Wayland_SortOutputsByPriorityHint(SDL_VideoData *vid)
SDL_free(str);
SDL_free(sorted_list);
-
- return true;
}
-
- return false;
}
static void Wayland_SortOutputs(SDL_VideoData *vid)
{
- bool have_primary = false;
-
- /* KDE provides the kde-output-order-v1 protocol, which gives us the full preferred display
- * ordering in the form of a list of wl_output.name strings.
- */
- if (!WAYLAND_wl_list_empty(&vid->output_order)) {
- SDL_WaylandConnectorName *c;
- SDL_DisplayData **sorted_list = SDL_malloc(sizeof(SDL_DisplayData *) * vid->output_count);
- int sorted_index = 0;
+ // Sort by position or connector name, so the order of outputs is deterministic.
+ SDL_qsort(vid->output_list, vid->output_count, sizeof(SDL_DisplayData *), Wayland_DisplayPositionCompare);
- if (sorted_list) {
- // Sort the outputs by connector name.
- wl_list_for_each (c, &vid->output_order, link) {
- for (int i = 0; i < vid->output_count; ++i) {
- SDL_DisplayData *d = vid->output_list[i];
- if (d && d->wl_output_name && SDL_strcmp(c->wl_output_name, d->wl_output_name) == 0) {
- sorted_list[sorted_index++] = d;
- vid->output_list[i] = NULL;
- break;
- }
- }
- }
-
- /* If any displays were omitted during the sort, append them to the new list.
- * This shouldn't happen, but better safe than sorry.
- */
- for (int i = 0; i < vid->output_count; ++i) {
- if (vid->output_list[i]) {
- sorted_list[sorted_index++] = vid->output_list[i];
- }
- }
-
- // Copy the sorted list to the output list.
- SDL_memcpy(vid->output_list, sorted_list, sizeof(SDL_DisplayData *) * vid->output_count);
- SDL_free(sorted_list);
-
- have_primary = true;
- }
- } else {
- // Sort by position or connector name, so the order of outputs is deterministic.
- SDL_qsort(vid->output_list, vid->output_count, sizeof(SDL_DisplayData *), Wayland_DisplayPositionCompare);
+ // Find a suitable primary display and move it to the front of the list.
+ const int primary_index = Wayland_GetPrimaryDisplay(vid);
+ if (primary_index) {
+ SDL_DisplayData *primary = vid->output_list[primary_index];
+ SDL_memmove(&vid->output_list[1], &vid->output_list[0], sizeof(SDL_DisplayData *) * primary_index);
+ vid->output_list[0] = primary;
}
- // Apply the ordering hint if specified, otherwise, try to find the primary display, if no preferred order is known.
- if (!Wayland_SortOutputsByPriorityHint(vid) && !have_primary) {
- const int primary_index = Wayland_GetPrimaryDisplay(vid);
- if (primary_index) {
- SDL_DisplayData *primary = vid->output_list[primary_index];
- SDL_memmove(&vid->output_list[1], &vid->output_list[0], sizeof(SDL_DisplayData *) * primary_index);
- vid->output_list[0] = primary;
- }
- }
+ // Apply the ordering hint, if specified.
+ Wayland_SortOutputsByPriorityHint(vid);
}
static void display_handle_done(void *data, struct wl_output *output);
@@ -643,7 +559,6 @@ static SDL_VideoDevice *Wayland_CreateDevice(bool require_preferred_protocols)
data->input = input;
data->display_externally_owned = display_is_external;
data->scale_to_display_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_SCALE_TO_DISPLAY, false);
- WAYLAND_wl_list_init(&data->output_order);
WAYLAND_wl_list_init(&external_window_list);
// Initialize all variables that we clean on shutdown
@@ -1353,9 +1268,6 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint
d->wp_alpha_modifier_v1 = wl_registry_bind(d->registry, id, &wp_alpha_modifier_v1_interface, 1);
} else if (SDL_strcmp(interface, "xdg_toplevel_icon_manager_v1") == 0) {
d->xdg_toplevel_icon_manager_v1 = wl_registry_bind(d->registry, id, &xdg_toplevel_icon_manager_v1_interface, 1);
- } else if (SDL_strcmp(interface, "kde_output_order_v1") == 0) {
- d->kde_output_order = wl_registry_bind(d->registry, id, &kde_output_order_v1_interface, 1);
- kde_output_order_v1_add_listener(d->kde_output_order, &kde_output_order_listener, d);
} else if (SDL_strcmp(interface, "frog_color_management_factory_v1") == 0) {
d->frog_color_management_factory_v1 = wl_registry_bind(d->registry, id, &frog_color_management_factory_v1_interface, 1);
}
@@ -1634,12 +1546,6 @@ static void Wayland_VideoCleanup(SDL_VideoDevice *_this)
data->xdg_toplevel_icon_manager_v1 = NULL;
}
- if (data->kde_output_order) {
- Wayland_FlushOutputOrder(data);
- kde_output_order_v1_destroy(data->kde_output_order);
- data->kde_output_order = NULL;
- }
-
if (data->frog_color_management_factory_v1) {
frog_color_management_factory_v1_destroy(data->frog_color_management_factory_v1);
data->frog_color_management_factory_v1 = NULL;
diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h
index 8d6c8a8627352..11ad075478206 100644
--- a/src/video/wayland/SDL_waylandvideo.h
+++ b/src/video/wayland/SDL_waylandvideo.h
@@ -91,9 +91,6 @@ struct SDL_VideoData
SDL_DisplayData **output_list;
int output_count;
int output_max;
- struct wl_list output_order;
-
- bool output_order_finalized;
int relative_mouse_mode;
bool display_externally_owned;
diff --git a/wayland-protocols/kde-output-order-v1.xml b/wayland-protocols/kde-output-order-v1.xml
deleted file mode 100644
index cc50f09efabdf..0000000000000
--- a/wayland-protocols/kde-output-order-v1.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<protocol name="kde_output_order_v1">
- <copyright><![CDATA[
- SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
-
- SPDX-License-Identifier: MIT-CMU
- ]]></copyright>
-
- <interface name="kde_output_order_v1" version="1">
- <description summary="announce order of outputs">
- Announce the order in which desktop environment components should be placed on outputs.
- The compositor will send the list of outputs when the global is bound and whenever there is a change.
- </description>
-
- <event name="output">
- <description summary="output name">
- Specifies the output identified by their wl_output.name.
- </description>
- <arg name="output_name" type="string" summary="the name of the output"/>
- </event>
-
- <event name="done">
- <description summary="done">
- Specifies that the output list is complete. On the next output event, a new list begins.
- </description>
- </event>
-
- <request name="destroy" type="destructor">
- <description summary="Destroy the output order notifier."/>
- </request>
- </interface>
-
-</protocol>