diff --git a/CMakeLists.txt b/CMakeLists.txt index 997523020..472979a33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.16) #make a universal binary on macOS set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE) -project(Clipboard LANGUAGES CXX C VERSION 0.8.1) -set(CMAKE_CXX_STANDARD 20) +project(Clipboard LANGUAGES CXX C VERSION 0.8.2) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED True) if (UNIX AND NOT APPLE AND NOT HAIKU AND NOT ANDROID) diff --git a/src/cb/src/clipboard.hpp b/src/cb/src/clipboard.hpp index 131fcd633..bdaa30bfb 100644 --- a/src/cb/src/clipboard.hpp +++ b/src/cb/src/clipboard.hpp @@ -339,7 +339,6 @@ std::string formatBytes(const auto& bytes) { } void verifyClipboardName(); -void updateRemoteClipboard(bool force = false); void setupGUIClipboardDaemon(); void syncWithRemoteClipboard(bool force = false); void syncWithGUIClipboard(bool force = false); diff --git a/src/cb/src/externalclipboards.cpp b/src/cb/src/externalclipboards.cpp index 3441f7fec..66e2edd32 100644 --- a/src/cb/src/externalclipboards.cpp +++ b/src/cb/src/externalclipboards.cpp @@ -209,6 +209,23 @@ void syncWithRemoteClipboard(bool force) { } } +void syncWithGUIClipboard(bool force) { + using enum ClipboardContentType; + if ((!isAClearingAction() && clipboard_name == constants.default_clipboard_name && clipboard_entry == constants.default_clipboard_entry && action != Action::Status) + || force) { // exclude Status because it does this manually + ClipboardContent content; + if (envVarIsTrue("CLIPBOARD_NOGUI")) return; + content = getGUIClipboard(preferred_mime); + if (content.type() == Text) { + convertFromGUIClipboard(content.text()); + copying.mime = !content.mime().empty() ? content.mime() : inferMIMEType(content.text()).value_or("text/plain"); + } else if (content.type() == Paths) { + convertFromGUIClipboard(content.paths()); + copying.mime = "text/uri-list"; + } + } +} + void syncWithExternalClipboards(bool force) { using enum ClipboardContentType; if ((!isAClearingAction() && clipboard_name == constants.default_clipboard_name && clipboard_entry == constants.default_clipboard_entry && action != Action::Status) @@ -277,13 +294,6 @@ void updateExternalClipboards(bool force) { } } -void updateRemoteClipboard(bool force) { - if ((isAWriteAction() && clipboard_name == constants.default_clipboard_name) || force) { // only update GUI clipboard on write operations - auto thisContent = thisClipboard(); - if (!envVarIsTrue("CLIPBOARD_NOREMOTE")) writeToRemoteClipboard(thisContent); - } -} - void setupGUIClipboardDaemon() { if (envVarIsTrue("CLIPBOARD_NOGUI")) return; @@ -309,26 +319,33 @@ void setupGUIClipboardDaemon() { #if defined(__linux__) // check if there is already a cb daemon by checking /proc for a process which has an exe symlink entry that points to a binary called "cb" and which does not have stdin or stdout file descriptors - for (const auto& entry : fs::directory_iterator("/proc")) { - if (!entry.is_directory()) continue; - auto exe = entry.path() / "exe"; - if (!fs::exists(exe)) continue; - auto exeTarget = fs::read_symlink(exe); - if (exeTarget.filename() != "cb") continue; - auto fd = entry.path() / "fd"; - if (fs::exists(fd / "0") || fs::exists(fd / "1") || fs::exists(fd / "2")) continue; - // found a cb daemon - exit(EXIT_SUCCESS); - } + try { + for (const auto& entry : fs::directory_iterator("/proc")) { + if (!entry.is_directory()) continue; + auto exe = entry.path() / "exe"; + if (!fs::exists(exe)) continue; + auto exeTarget = fs::read_symlink(exe); + if (exeTarget.filename() != "cb") continue; + auto fd = entry.path() / "fd"; + if (fs::exists(fd / "0") || fs::exists(fd / "1") || fs::exists(fd / "2")) continue; + // found a cb daemon + exit(EXIT_SUCCESS); + } + } catch (...) {} + + // std::cerr << "Starting cb daemon" << std::endl; #endif #elif defined(_WIN32) | defined(_WIN64) #endif - using enum ClipboardContentType; - - while (true) { - ClipboardContent content = {}; + path = Clipboard(std::string(constants.default_clipboard_name)); - content = getGUIClipboard(""); + while (fs::exists(path)) { + path.getLock(); + syncWithGUIClipboard(true); + path.releaseLock(); + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); } + + exit(EXIT_SUCCESS); } \ No newline at end of file diff --git a/src/cb/src/main.cpp b/src/cb/src/main.cpp index 82ba34d06..061224c2a 100644 --- a/src/cb/src/main.cpp +++ b/src/cb/src/main.cpp @@ -75,11 +75,7 @@ int main(int argc, char* argv[]) { copying.mime = getMIMEType(); -#if defined(__linux__) - updateRemoteClipboard(); -#else updateExternalClipboards(); -#endif if (!copying.failedItems.empty()) clipboard_state = ClipboardState::Error; diff --git a/src/cb/src/utils.cpp b/src/cb/src/utils.cpp index 974f0018c..eac177563 100644 --- a/src/cb/src/utils.cpp +++ b/src/cb/src/utils.cpp @@ -534,27 +534,34 @@ void setClipboardAttributes() { void verifyClipboardName() { #if defined(_WIN32) || defined(_WIN64) - constexpr std::array forbiddenFilenameCharacters{ '<', '>', ':', '"', '/', '\\', '|', '?', '*' }; + constexpr std::array forbiddenFilenameCharacters {'<', '>', ':', '"', '/', '\\', '|', '?', '*'}; #elif defined(__APPLE__) - constexpr std::array forbiddenFilenameCharacters{ '/', ':' }; + constexpr std::array forbiddenFilenameCharacters {'/', ':'}; #elif defined(__linux__) || defined(__FreeBSD__) || defined(__unix__) - constexpr std::array forbiddenFilenameCharacters{ '/' }; + constexpr std::array forbiddenFilenameCharacters {'/'}; #else - constexpr std::array forbiddenFilenameCharacters{}; + constexpr std::array forbiddenFilenameCharacters {}; #endif #if defined(_WIN32) || defined(_WIN64) - for (const auto& forbiddenFilename : { "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", - "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", - "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" }) { + for (const auto& forbiddenFilename : + {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"}) { if (clipboard_name == forbiddenFilename) { - error_exit(formatColors("[error][inverse] ✘ [noinverse] The clipboard name you chose (\"[bold]%s[blank][error]\") won't work on this system possibly due to special characters. [help]⬤ Try choosing a different one instead.\n[blank]"), clipboard_name); + error_exit( + formatColors("[error][inverse] ✘ [noinverse] The clipboard name you chose (\"[bold]%s[blank][error]\") won't work on this system possibly due to special characters. [help]⬤ Try " + "choosing a different one instead.\n[blank]"), + clipboard_name + ); } } #endif if (std::find_first_of(clipboard_name.begin(), clipboard_name.end(), forbiddenFilenameCharacters.begin(), forbiddenFilenameCharacters.end()) != clipboard_name.end()) { - error_exit(formatColors("[error][inverse] ✘ [noinverse] The clipboard name you chose (\"[bold]%s[blank][error]\") won't work on this system possibly due to special characters. [help]⬤ Try choosing a different one instead.\n[blank]"), clipboard_name); + error_exit( + formatColors("[error][inverse] ✘ [noinverse] The clipboard name you chose (\"[bold]%s[blank][error]\") won't work on this system possibly due to special characters. [help]⬤ Try " + "choosing a different one instead.\n[blank]"), + clipboard_name + ); } }