Skip to content

Commit

Permalink
osdep/file_dialog-unix: add fallback to external dialogs if portal fails
Browse files Browse the repository at this point in the history
  • Loading branch information
kasper93 committed Feb 13, 2025
1 parent e612e2a commit 322f76e
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 8 deletions.
7 changes: 5 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,11 @@ if not posix and not features['win32-desktop']
'osdep/terminal-dummy.c')
endif

if not win32 and not darwin
sources += files('osdep/file_dialog-external.c',
'osdep/file_dialog-unix.c')
endif

# media controls
if win32
subdir('osdep/win32')
Expand Down Expand Up @@ -706,8 +711,6 @@ features += {'libportal': libportal.found()}
if features['libportal']
sources += files('osdep/file_dialog-portal.c')
dependencies += libportal
elif not win32 and not darwin
sources += files('osdep/file_dialog-external.c')
endif

libm = cc.find_library('m', required: false)
Expand Down
8 changes: 6 additions & 2 deletions osdep/file_dialog-external.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/

#include "file_dialog.h"
#include "file_dialog-external.h"

#include <player/core.h>

Expand Down Expand Up @@ -132,7 +132,9 @@ static const dialog_func_t dialogs[] = {
NULL,
};

char **mp_file_dialog_get_files(void *talloc_ctx, const mp_file_dialog_params *params)
char **mp_file_dialog_get_files_external(void *talloc_ctx,
const mp_file_dialog_params *params,
bool *error)
{
void *tmp = talloc_new(NULL);
const char *args[MAX_ARGS] = {0};
Expand Down Expand Up @@ -166,6 +168,8 @@ char **mp_file_dialog_get_files(void *talloc_ctx, const mp_file_dialog_params *p
break;
}

*error = res.error != MP_SUBPROCESS_OK;

char **ret = NULL;
size_t ret_count = 0;
if (res.error == MP_SUBPROCESS_OK && res.exit_status == 0) {
Expand Down
24 changes: 24 additions & 0 deletions osdep/file_dialog-external.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "file_dialog.h"

char **mp_file_dialog_get_files_external(void *talloc_ctx,
const mp_file_dialog_params *params,
bool *error);
24 changes: 20 additions & 4 deletions osdep/file_dialog-portal.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/

#include "file_dialog.h"
#include "file_dialog-portal.h"

#include <libportal/portal.h>

Expand All @@ -25,20 +25,33 @@ typedef GVariant *(*finish_t)(XdpPortal *portal, GAsyncResult *result, GError **

struct portal_data {
char **files;
bool *error;
GMainLoop *loop;
finish_t finish;
};

static void handle_response(GObject *object, GAsyncResult *result, gpointer user_data)
{
struct portal_data *data = user_data;
GVariant *response = data->finish(XDP_PORTAL(object), result, NULL);
GError *error = NULL;
GVariant *response = data->finish(XDP_PORTAL(object), result, &error);

if (data->loop) {
g_main_loop_quit(data->loop);
g_main_loop_unref(data->loop);
}

if (error) {
gint code = error->code;
g_error_free(error);
// Apparently G_IO_ERROR_FAILED is used when dialog is closed, we
// shouldn't fallback in this case.
if (code != G_IO_ERROR_CANCELLED && code != G_IO_ERROR_FAILED)
return;
}

*data->error = false;

if (!response)
return;

Expand Down Expand Up @@ -89,10 +102,13 @@ static GVariant *convert_filters_to_gvariant(const mp_file_dialog_filters *f)
return g_variant_builder_end(&filter_builder);
}

char **mp_file_dialog_get_files(void *talloc_ctx, const mp_file_dialog_params *params)
char **mp_file_dialog_get_files_portal(void *talloc_ctx,
const mp_file_dialog_params *params,
bool *error)
{
XdpPortal *portal = xdp_portal_initable_new(NULL);
struct portal_data data = {0};
struct portal_data data = { .error = error };
*data.error = true;

if (!portal)
return NULL;
Expand Down
24 changes: 24 additions & 0 deletions osdep/file_dialog-portal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "file_dialog.h"

char **mp_file_dialog_get_files_portal(void *talloc_ctx,
const mp_file_dialog_params *params,
bool *error);
48 changes: 48 additions & 0 deletions osdep/file_dialog-unix.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/

#include "file_dialog.h"

#include <stddef.h>

#include <config.h>

#include "file_dialog-portal.h"
#include "file_dialog-external.h"

typedef char **(*get_files_t)(void *talloc_ctx, const mp_file_dialog_params *params, bool *error);

static const get_files_t dialogs[] = {
#if HAVE_LIBPORTAL
mp_file_dialog_get_files_portal,
#endif
mp_file_dialog_get_files_external,
NULL,
};

char **mp_file_dialog_get_files(void *talloc_ctx, const mp_file_dialog_params *params)
{
for (int i = 0; dialogs[i]; i++) {
bool error = false;
char **files = dialogs[i](talloc_ctx, params, &error);
if (files)
return files;
if (!error)
break;
}
return NULL;
}

0 comments on commit 322f76e

Please sign in to comment.