misc: Use the OpenURI D-Bus portal for opening URLs

This works inside of containers, and supports passing an activation token with the request, which is needed on Wayland to transfer focus to the browser.
This commit is contained in:
Frank Praznik
2026-04-04 22:28:06 -04:00
parent f8feccfa46
commit 682da4ee98
6 changed files with 307 additions and 11 deletions

View File

@@ -471,6 +471,63 @@ static bool SDL_DBus_AppendDictWithKeyValue(DBusMessageIter *iterInit, const cha
return SDL_DBus_AppendDictWithKeysAndValues(iterInit, keys, values, 1);
}
bool SDL_DBus_OpenURI(const char *uri, const char *window_id, const char *activation_token)
{
const char *bus_name = "org.freedesktop.portal.Desktop";
const char *path = "/org/freedesktop/portal/desktop";
const char *interface = "org.freedesktop.portal.OpenURI";
DBusMessageIter iterInit;
bool ret = false;
if (!dbus.session_conn) {
/* We either lost connection to the session bus or were not able to
* load the D-Bus library at all.
*/
return false;
}
DBusMessage *msg = dbus.message_new_method_call(bus_name, path, interface, "OpenURI");
if (!msg) {
return false;
}
if (!window_id) {
window_id = "";
}
if (!dbus.message_append_args(msg, DBUS_TYPE_STRING, &window_id, DBUS_TYPE_STRING, &uri, DBUS_TYPE_INVALID)) {
goto done;
}
dbus.message_iter_init_append(msg, &iterInit);
if (activation_token) {
if (!SDL_DBus_AppendDictWithKeyValue(&iterInit, "activation_token", activation_token)) {
goto done;
}
} else {
// The array must be in the parameter list, even if empty.
DBusMessageIter iterArray;
if (!dbus.message_iter_open_container(&iterInit, DBUS_TYPE_ARRAY, "{sv}", &iterArray)) {
goto done;
}
if (!dbus.message_iter_close_container(&iterInit, &iterArray)) {
goto done;
}
}
{
DBusMessage *reply = dbus.connection_send_with_reply_and_block(dbus.session_conn, msg, -1, NULL);
if (reply) {
ret = true;
dbus.message_unref(reply);
}
}
done:
dbus.message_unref(msg);
return ret;
}
bool SDL_DBus_ScreensaverInhibit(bool inhibit)
{
const char *default_inhibit_reason = "Playing a game";

View File

@@ -119,6 +119,8 @@ extern void SDL_DBus_FreeReply(DBusMessage **saved_reply);
extern void SDL_DBus_ScreensaverTickle(void);
extern bool SDL_DBus_ScreensaverInhibit(bool inhibit);
extern bool SDL_DBus_OpenURI(const char *uri, const char *window_id, const char *activation_token);
extern void SDL_DBus_PumpEvents(void);
extern char *SDL_DBus_GetLocalMachineId(void);