| 384 | constexpr auto* cFileChooserInterface = "org.freedesktop.portal.FileChooser"; |
| 385 | |
| 386 | bool isPortalFileDialogSupported() |
| 387 | { |
| 388 | static bool sIsSupported = [] |
| 389 | { |
| 390 | auto* conn = getConnection(); |
| 391 | if ( !conn ) |
| 392 | return false; |
| 393 | |
| 394 | DBusError err; |
| 395 | dbus_error_init( &err ); |
| 396 | MR_FINALLY { dbus_error_free( &err ); }; |
| 397 | |
| 398 | if ( !dbus_bus_name_has_owner( conn, cPortalServiceName, &err ) ) |
| 399 | { |
| 400 | spdlog::warn( "XDG Desktop Portal implementation is not found" ); |
| 401 | return false; |
| 402 | } |
| 403 | if ( dbus_error_is_set( &err ) ) |
| 404 | { |
| 405 | spdlog::warn( "DBus error: {}", err.message ); |
| 406 | return false; |
| 407 | } |
| 408 | |
| 409 | auto* callMsg = dbus_message_new_method_call( cPortalServiceName, cPortalObjectPath, "org.freedesktop.DBus.Properties", "Get" ); |
| 410 | DBusMessageIter argsIter; |
| 411 | dbus_message_iter_init_append( callMsg, &argsIter ); |
| 412 | dbusAppend( argsIter, cFileChooserInterface ); |
| 413 | dbusAppend( argsIter, "version" ); |
| 414 | |
| 415 | auto* reply = dbus_connection_send_with_reply_and_block( conn, callMsg, DBUS_TIMEOUT_INFINITE, &err ); |
| 416 | dbus_connection_flush( conn ); |
| 417 | dbus_message_unref( callMsg ); |
| 418 | if ( !reply || dbus_error_is_set( &err ) ) |
| 419 | { |
| 420 | spdlog::warn( "Failed to send DBus message: {}", err.message ); |
| 421 | return false; |
| 422 | } |
| 423 | |
| 424 | DBusMessageIter respIter; |
| 425 | dbus_message_iter_init( reply, &respIter ); |
| 426 | assert( dbus_message_iter_get_arg_type( &respIter ) == DBUS_TYPE_VARIANT ); |
| 427 | DBusMessageIter varIter; |
| 428 | dbus_message_iter_recurse( &respIter, &varIter ); |
| 429 | assert( dbus_message_iter_get_arg_type( &varIter ) == DBUS_TYPE_UINT32 ); |
| 430 | uint32_t version; |
| 431 | dbus_message_iter_get_basic( &varIter, &version ); |
| 432 | spdlog::info( "File Chooser portal found: version {}", version ); |
| 433 | |
| 434 | return true; |
| 435 | } (); |
| 436 | return sIsSupported; |
| 437 | } |
| 438 | |
| 439 | std::vector<std::filesystem::path> runPortalFileDialog( const MR::FileDialog::Parameters& params ) |
| 440 | { |
no test coverage detected