Client.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * Copyright (c) 2021, timmot <tiwwot@protonmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. // FIXME: LibIPC Decoder and Encoder are sensitive to include order here
  7. // clang-format off
  8. #include <LibGUI/WindowServerConnection.h>
  9. // clang-format on
  10. #include <AK/LexicalPath.h>
  11. #include <LibCore/File.h>
  12. #include <LibFileSystemAccessClient/Client.h>
  13. #include <LibGUI/Window.h>
  14. namespace FileSystemAccessClient {
  15. static RefPtr<Client> s_the = nullptr;
  16. Client& Client::the()
  17. {
  18. if (!s_the || !s_the->is_open())
  19. s_the = Client::construct();
  20. return *s_the;
  21. }
  22. Result Client::request_file_read_only_approved(i32 parent_window_id, String const& path)
  23. {
  24. m_promise = Core::Promise<Result>::construct();
  25. auto parent_window_server_client_id = GUI::WindowServerConnection::the().expose_client_id();
  26. auto child_window_server_client_id = expose_window_server_client_id();
  27. GUI::WindowServerConnection::the().async_add_window_stealing_for_client(child_window_server_client_id, parent_window_id);
  28. ScopeGuard guard([parent_window_id, child_window_server_client_id] {
  29. GUI::WindowServerConnection::the().async_remove_window_stealing_for_client(child_window_server_client_id, parent_window_id);
  30. });
  31. if (path.starts_with('/')) {
  32. async_request_file_read_only_approved(parent_window_server_client_id, parent_window_id, path);
  33. } else {
  34. auto full_path = LexicalPath::join(Core::File::current_working_directory(), path).string();
  35. async_request_file_read_only_approved(parent_window_server_client_id, parent_window_id, full_path);
  36. }
  37. return m_promise->await();
  38. }
  39. Result Client::request_file(i32 parent_window_id, String const& path, Core::OpenMode mode)
  40. {
  41. m_promise = Core::Promise<Result>::construct();
  42. auto parent_window_server_client_id = GUI::WindowServerConnection::the().expose_client_id();
  43. auto child_window_server_client_id = expose_window_server_client_id();
  44. GUI::WindowServerConnection::the().async_add_window_stealing_for_client(child_window_server_client_id, parent_window_id);
  45. ScopeGuard guard([parent_window_id, child_window_server_client_id] {
  46. GUI::WindowServerConnection::the().async_remove_window_stealing_for_client(child_window_server_client_id, parent_window_id);
  47. });
  48. if (path.starts_with('/')) {
  49. async_request_file(parent_window_server_client_id, parent_window_id, path, mode);
  50. } else {
  51. auto full_path = LexicalPath::join(Core::File::current_working_directory(), path).string();
  52. async_request_file(parent_window_server_client_id, parent_window_id, full_path, mode);
  53. }
  54. return m_promise->await();
  55. }
  56. Result Client::open_file(i32 parent_window_id, String const& window_title, StringView path, Core::OpenMode requested_access)
  57. {
  58. m_promise = Core::Promise<Result>::construct();
  59. auto parent_window_server_client_id = GUI::WindowServerConnection::the().expose_client_id();
  60. auto child_window_server_client_id = expose_window_server_client_id();
  61. GUI::WindowServerConnection::the().async_add_window_stealing_for_client(child_window_server_client_id, parent_window_id);
  62. ScopeGuard guard([parent_window_id, child_window_server_client_id] {
  63. GUI::WindowServerConnection::the().async_remove_window_stealing_for_client(child_window_server_client_id, parent_window_id);
  64. });
  65. async_prompt_open_file(parent_window_server_client_id, parent_window_id, window_title, path, requested_access);
  66. return m_promise->await();
  67. }
  68. Result Client::save_file(i32 parent_window_id, String const& name, String const ext, Core::OpenMode requested_access)
  69. {
  70. m_promise = Core::Promise<Result>::construct();
  71. auto parent_window_server_client_id = GUI::WindowServerConnection::the().expose_client_id();
  72. auto child_window_server_client_id = expose_window_server_client_id();
  73. GUI::WindowServerConnection::the().async_add_window_stealing_for_client(child_window_server_client_id, parent_window_id);
  74. ScopeGuard guard([parent_window_id, child_window_server_client_id] {
  75. GUI::WindowServerConnection::the().async_remove_window_stealing_for_client(child_window_server_client_id, parent_window_id);
  76. });
  77. async_prompt_save_file(parent_window_server_client_id, parent_window_id, name.is_null() ? "Untitled" : name, ext.is_null() ? "txt" : ext, Core::StandardPaths::home_directory(), requested_access);
  78. return m_promise->await();
  79. }
  80. void Client::handle_prompt_end(i32 error, Optional<IPC::File> const& fd, Optional<String> const& chosen_file)
  81. {
  82. VERIFY(m_promise);
  83. if (error == 0) {
  84. m_promise->resolve({ error, fd->take_fd(), *chosen_file });
  85. } else {
  86. m_promise->resolve({ error, {}, chosen_file });
  87. }
  88. }
  89. void Client::die()
  90. {
  91. if (m_promise)
  92. handle_prompt_end(ECONNRESET, {}, "");
  93. }
  94. }