Skip to content

Commit

Permalink
x11: Support sorting displays via the priority hint
Browse files Browse the repository at this point in the history
Store the connector name for displays and use it for sorting them according to priority, if the hint is set.
  • Loading branch information
Kontrabant committed Oct 18, 2024
1 parent c98f5cf commit 47867eb
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/SDL3/SDL_hints.h
Original file line number Diff line number Diff line change
Expand Up @@ -3158,6 +3158,7 @@ extern "C" {
*
* - KMSDRM (kmsdrm)
* - Wayland (wayland)
* - X11 (x11)
*
* This hint should be set before SDL is initialized.
*
Expand Down
49 changes: 49 additions & 0 deletions src/video/x11/SDL_x11modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ static bool X11_FillXRandRDisplayInfo(SDL_VideoDevice *_this, Display *dpy, int
displaydata->y = display_y;
displaydata->use_xrandr = true;
displaydata->xrandr_output = outputid;
SDL_strlcpy(displaydata->connector_name, display_name, sizeof(displaydata->connector_name));

SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode);
SetXRandRDisplayName(dpy, EDID, display_name, display_name_size, outputid, display_mm_width, display_mm_height);
Expand Down Expand Up @@ -751,6 +752,52 @@ void X11_HandleXRandREvent(SDL_VideoDevice *_this, const XEvent *xevent)
}
}

static void X11_SortOutputsByPriorityHint(SDL_VideoDevice *_this)
{
const char *name_hint = SDL_GetHint(SDL_HINT_VIDEO_DISPLAY_PRIORITY);

if (name_hint) {
char *saveptr;
char *str = SDL_strdup(name_hint);
SDL_VideoDisplay **sorted_list = SDL_malloc(sizeof(SDL_VideoDisplay *) * _this->num_displays);

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) {
for (int i = 0; i < _this->num_displays; ++i) {
SDL_VideoDisplay *d = _this->displays[i];
if (d) {
SDL_DisplayData *data = d->internal;
if (SDL_strcmp(token, data->connector_name) == 0) {
sorted_list[sorted_index++] = d;
_this->displays[i] = NULL;
break;
}
}
}

token = SDL_strtok_r(NULL, ",", &saveptr);
}

// Append the remaining displays to the end of the list.
for (int i = 0; i < _this->num_displays; ++i) {
if (_this->displays[i]) {
sorted_list[sorted_index++] = _this->displays[i];
}
}

// Copy the sorted list back to the display list.
SDL_memcpy(_this->displays, sorted_list, sizeof(SDL_VideoDisplay *) * _this->num_displays);
}

SDL_free(str);
SDL_free(sorted_list);
}
}

static bool X11_InitModes_XRandR(SDL_VideoDevice *_this)
{
SDL_VideoData *data = _this->internal;
Expand Down Expand Up @@ -810,6 +857,8 @@ static bool X11_InitModes_XRandR(SDL_VideoDevice *_this)
return SDL_SetError("No available displays");
}

X11_SortOutputsByPriorityHint(_this);

return true;
}
#endif // SDL_VIDEO_DRIVER_X11_XRANDR
Expand Down
1 change: 1 addition & 0 deletions src/video/x11/SDL_x11modes.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct SDL_DisplayData

#ifdef SDL_VIDEO_DRIVER_X11_XRANDR
RROutput xrandr_output;
char connector_name[16];
#endif
};

Expand Down

0 comments on commit 47867eb

Please sign in to comment.