From f6737becbfd3904461ed60eb7fcb9a047b47e094 Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Sat, 3 Feb 2024 23:59:04 +0100 Subject: Adapt Patch to 3.11.1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d65f50..dc3b84a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,7 +206,7 @@ if(BUILD_CLIENT) find_package(Sparkle) endif() - if(UNIX AND NOT APPLE) + if(UNIX AND NOT APPLE AND NOT HAIKU) find_package(Inotify REQUIRED) endif() find_package(Sphinx) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bf3ff9a..c7cdeaa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -68,7 +68,7 @@ if(NOT TOKEN_AUTH_ONLY) endif() # TODO: Mingw64 7.3 might also need to be excluded here as it seems to not automatically link libssp -if(NOT MSVC) +if(NOT MSVC AND NOT HAIKU) if(NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "^(alpha|parisc|hppa)") AND NOT CMAKE_CROSSCOMPILING) if((CMAKE_CXX_COMPILER_ID MATCHES "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector --param=ssp-buffer-size=4") diff --git a/src/common/common.cmake b/src/common/common.cmake index 1265427..028aeac 100644 --- a/src/common/common.cmake +++ b/src/common/common.cmake @@ -25,7 +25,11 @@ elseif(APPLE) list(APPEND common_SOURCES ${CMAKE_CURRENT_LIST_DIR}/utility_mac.mm ) -elseif(UNIX AND NOT APPLE) +elseif(HAIKU) + list(APPEND common_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/utility_haiku.cpp + ) +elseif(UNIX AND NOT APPLE AND NOT HAIKU) list(APPEND common_SOURCES ${CMAKE_CURRENT_LIST_DIR}/utility_unix.cpp ) diff --git a/src/common/utility.cpp b/src/common/utility.cpp index e4eff93..2c06960 100644 --- a/src/common/utility.cpp +++ b/src/common/utility.cpp @@ -45,6 +45,12 @@ #include #endif +#ifdef Q_OS_HAIKU +#include +#include +#include +#endif + #include #include #include @@ -153,6 +159,8 @@ static QLatin1String platform() return QLatin1String("DragonFlyBSD"); #elif defined(Q_OS_FREEBSD) || defined(Q_OS_FREEBSD_KERNEL) return QLatin1String("FreeBSD"); +#elif defined(Q_OS_HAIKU) + return QLatin1String("Haiku"); #elif defined(Q_OS_NETBSD) return QLatin1String("NetBSD"); #elif defined(Q_OS_OPENBSD) @@ -186,7 +194,7 @@ QByteArray Utility::friendlyUserAgentString() qint64 Utility::freeDiskSpace(const QString &path) { -#if defined(Q_OS_MAC) || defined(Q_OS_FREEBSD) || defined(Q_OS_FREEBSD_KERNEL) || defined(Q_OS_NETBSD) || defined(Q_OS_OPENBSD) +#if defined(Q_OS_MAC) || defined(Q_OS_FREEBSD) || defined(Q_OS_FREEBSD_KERNEL) || defined(Q_OS_HAIKU) || defined(Q_OS_NETBSD) || defined(Q_OS_OPENBSD) struct statvfs stat; if (statvfs(path.toLocal8Bit().data(), &stat) == 0) { return (qint64)stat.f_bavail * stat.f_frsize; diff --git a/src/common/utility.h b/src/common/utility.h index bd62a5d..f021849 100644 --- a/src/common/utility.h +++ b/src/common/utility.h @@ -134,6 +134,7 @@ namespace Utility { inline bool isUnix(); inline bool isLinux(); // use with care inline bool isBSD(); // use with care, does not match OS X + inline bool isHaiku(); OCSYNC_EXPORT QString platformName(); // crash helper for --debug @@ -341,5 +342,14 @@ inline bool Utility::isBSD() #endif } +inline bool Utility::isHaiku() +{ +#if defined(Q_OS_HAIKU) + return true; +#else + return false; +#endif +} + } #endif // UTILITY_H diff --git a/src/common/utility_haiku.cpp b/src/common/utility_haiku.cpp new file mode 100644 index 0000000..fa876e4 --- /dev/null +++ b/src/common/utility_haiku.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) by Klaas Freitag + * Copyright (C) by Daniel Molkentin + * + * This library 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. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "utility.h" +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace OCC { + +void Utility::setupFavLink(const QString &folder) +{ + Q_UNUSED(folder); + // Haiku doesn't really have that concept of bookmarks on folders +} + +void Utility::removeFavLink(const QString &folder) +{ + Q_UNUSED(folder); + // Haiku doesn't really have that concept of bookmarks on folders +} + +// returns the autostart directory the Haiku way +// should probably use launch_daemon service directly though +// instead of the old way +static QString getUserAutostartDir() +{ + BPath path; + find_directory(B_USER_SETTINGS_DIRECTORY, &path); + QString config = QString::fromUtf8(path.Path()); + config += QLatin1String("/boot/launch/"); + return config; +} + +bool Utility::hasSystemLaunchOnStartup(const QString &appName) +{ + Q_UNUSED(appName) + return false; +} + +bool Utility::hasLaunchOnStartup(const QString &appName) +{ + QString startupFileLocation = getUserAutostartDir() + appName; + return QFile::exists(startupFileLocation); +} + +void Utility::setLaunchOnStartup(const QString &appName, const QString &guiName, bool enable) +{ + const auto userAutoStartPath = getUserAutostartDir(); + QString startupFileLocation = userAutoStartPath + appName; + if (enable) { + if (!QDir().exists(userAutoStartPath) && !QDir().mkpath(userAutoStartPath)) { + qCWarning(lcUtility) << "Could not create autostart folder" << userAutoStartPath; + return; + } + if (!QFile::link(QCoreApplication::applicationFilePath(), startupFileLocation)) { + qCWarning(lcUtility) << "Could not write autostart symlink" << startupFileLocation; + return; + } + } else { + if (!QFile::remove(startupFileLocation)) { + qCWarning(lcUtility) << "Could not remove autostart symlink"; + } + } +} + +bool Utility::hasDarkSystray() +{ + return true; +} + +QString Utility::getCurrentUserName() +{ + return {}; +} + +void Utility::registerUriHandlerForLocalEditing() +{ + const auto appImagePath = qEnvironmentVariable("APPIMAGE"); + const auto runningInsideAppImage = !appImagePath.isNull() && QFile::exists(appImagePath); + + if (!runningInsideAppImage) { + // only register x-scheme-handler if running inside appImage + return; + } + + // mirall.desktop.in must have an x-scheme-handler mime type specified + const QString desktopFileName = QLatin1String(LINUX_APPLICATION_ID) + QLatin1String(".desktop"); + QProcess process; + const QStringList args = { + QLatin1String("default"), + desktopFileName, + QStringLiteral("x-scheme-handler/%1").arg(QStringLiteral(APPLICATION_URI_HANDLER_SCHEME)) + }; + process.start(QStringLiteral("xdg-mime"), args, QIODevice::ReadOnly); + process.waitForFinished(); +} + +} // namespace OCC diff --git a/src/csync/CMakeLists.txt b/src/csync/CMakeLists.txt index 382eab2..455e820 100644 --- a/src/csync/CMakeLists.txt +++ b/src/csync/CMakeLists.txt @@ -72,7 +72,7 @@ generate_export_header(nextcloud_csync target_link_libraries(nextcloud_csync PUBLIC ${CSYNC_REQUIRED_LIBRARIES} - Qt5::Core Qt5::Concurrent + Qt5::Core Qt5::Concurrent be ) if(ZLIB_FOUND) diff --git a/src/csync/std/c_private.h b/src/csync/std/c_private.h index 8307859..0ddcaa8 100644 --- a/src/csync/std/c_private.h +++ b/src/csync/std/c_private.h @@ -85,7 +85,7 @@ using csync_stat_t = struct stat; #endif #ifndef HAVE_LSTAT -#define lstat _stat +#define lstat stat #endif /* tchar definitions for clean win32 filenames */ diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 1968683..e81b1fe 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -311,7 +311,7 @@ IF( APPLE ) endif() ENDIF() -IF( NOT WIN32 AND NOT APPLE ) +IF( NOT WIN32 AND NOT APPLE AND NOT HAIKU ) set(client_SRCS ${client_SRCS} folderwatcher_linux.cpp) ENDIF() IF( WIN32 ) @@ -320,6 +320,9 @@ ENDIF() IF( APPLE ) list(APPEND client_SRCS folderwatcher_mac.cpp) ENDIF() +IF( APPLE ) +list(APPEND client_SRCS folderwatcher_haiku.cpp) +ENDIF() set(3rdparty_SRC ../3rdparty/QProgressIndicator/QProgressIndicator.h @@ -537,6 +540,7 @@ target_link_libraries(nextcloudCore Qt5::Quick Qt5::QuickControls2 KF5::Archive + be ) add_subdirectory(socketapi) diff --git a/src/gui/folderwatcher.cpp b/src/gui/folderwatcher.cpp index 0743646..5d01a95 100644 --- a/src/gui/folderwatcher.cpp +++ b/src/gui/folderwatcher.cpp @@ -23,6 +23,8 @@ #include "folderwatcher_win.h" #elif defined(Q_OS_MAC) #include "folderwatcher_mac.h" +#elif defined(Q_OS_HAIKU) +#include "folderwatcher_haiku.h" #elif defined(Q_OS_UNIX) #include "folderwatcher_linux.h" #endif @@ -128,6 +130,10 @@ void FolderWatcher::startNotificatonTest(const QString &path) return; #endif +#ifdef Q_OS_HAIKU + return; +#endif + Q_ASSERT(_testNotificationPath.isEmpty()); _testNotificationPath = path; diff --git a/src/gui/folderwatcher_haiku.cpp b/src/gui/folderwatcher_haiku.cpp new file mode 100644 index 0000000..21e6fe4 --- /dev/null +++ b/src/gui/folderwatcher_haiku.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) by François Revol + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License + * for more details. + */ +#include "config.h" + +#include "folder.h" +#include "folderwatcher.h" +#include "folderwatcher_haiku.h" + + +#include +#include +#include + +#include +#include +#include +#include + + + +namespace OCC { + + +void WatcherHandler::MessageReceived(BMessage* message) +{ + qCDebug(lcFolderWatcher) << "WatcherHandler::MessageReceived()" << message->what; + if (message->what != B_PATH_MONITOR) { + BHandler::MessageReceived(message); + return; + } + + int32 opcode; + if (message->FindInt32("opcode", &opcode) != B_OK) + return; + + const char *path = NULL; + if (message->FindString("path", &path) != B_OK) + return; + + // get the filename + // sometimes we have it in the message, but not always + BPath p(path); + BString fileName(p.Leaf()); + if (fileName.StartsWith("._sync_") + || fileName.StartsWith(".csync_journal.db") + || fileName.StartsWith(".nextloudsync.log") + || fileName.StartsWith(".sync_")) { + return; + } + + int32 fields; + QStringList paths; + + switch (opcode) { + case B_ENTRY_MOVED: + { + const char *from = NULL; + if (message->FindString("from path", &from) != B_OK) + return; + QString qFrom = QString::fromUtf8(from); + paths.append(qFrom); + break; + } + case B_ENTRY_CREATED: + case B_ENTRY_REMOVED: + break; + case B_STAT_CHANGED: + if (message->FindInt32("fields", &fields) != B_OK) + return; + // we're only interested in mtime + // and content change... which should always change mtime though + // just to be sure, check size changes as well + if (fields & (B_STAT_MODIFICATION_TIME | B_STAT_SIZE)) + break; + return; + case B_ATTR_CHANGED: + // TODO: it is just unacceptable to not handle xattrs on Haiku! + // but it must be done properly, + // cf. http://dcevents.dublincore.org/IntConf/dc-2011/paper/view/53 + default: + // discard + return; + } + + //message->PrintToStream(); + + QString qPath = QString::fromUtf8(path); + paths.append(qPath); + emit changed(paths); +} + + +FolderWatcherPrivate::FolderWatcherPrivate(FolderWatcher *p, const QString &path) + : _parent(p) + , _folder(path) + , _handler(new WatcherHandler) +{ + this->startWatching(); +} + +FolderWatcherPrivate::~FolderWatcherPrivate() +{ + BPrivate::BPathMonitor::StopWatching(BMessenger(_handler)); + be_app->Lock(); + be_app->RemoveHandler(_handler); + be_app->Unlock(); + delete _handler; +} + +void FolderWatcherPrivate::startWatching() +{ + qCDebug(lcFolderWatcher) << "FolderWatcherPrivate::startWatching()" << _folder; + + // it needs to be attached to a BLooper, which be_app happens to be. + be_app->Lock(); + be_app->AddHandler(_handler); + be_app->Unlock(); + + connect(_handler, SIGNAL(changed(const QStringList &)), + _parent, SLOT(changeDetected(const QStringList &))); + connect(_handler, SIGNAL(lostChanges()), + _parent, SIGNAL(lostChanges())); + + BMessenger messenger(_handler); + uint32 flags = B_WATCH_RECURSIVELY | B_WATCH_NAME | B_WATCH_STAT; + status_t err; + err = BPrivate::BPathMonitor::StartWatching(_folder.toUtf8().constData(), flags, messenger); + if (err != B_OK) + qCWarning(lcFolderWatcher) << "BPathMonitor::StartWatching failed: " << strerror(err); +} + + +} // ns mirall diff --git a/src/gui/folderwatcher_haiku.h b/src/gui/folderwatcher_haiku.h new file mode 100644 index 0000000..6bf7091 --- /dev/null +++ b/src/gui/folderwatcher_haiku.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) by François Revol + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License + * for more details. +*/ + +#define FOLDERWATCHER_HAIKU_H + +#include +#include + +#include + +namespace OCC { + +/** + * @brief The WatcherHandler class + * @ingroup gui + */ +class WatcherHandler : public QObject, public BHandler { + Q_OBJECT +public: + WatcherHandler() : QObject(), BHandler("FolderWatcher") {} + virtual ~WatcherHandler() {} + virtual void MessageReceived(BMessage* message); + +signals: + void changed(const QStringList &paths); + void lostChanges(); + +private: + QString _path; +}; + +/** + * @brief Haiku API implementation of FolderWatcher + * @ingroup gui + */ +class FolderWatcherPrivate : public QObject +{ + Q_OBJECT +public: + FolderWatcherPrivate(FolderWatcher *p, const QString &path); + ~FolderWatcherPrivate(); + + void addPath(const QString &) {} + void removePath(const QString &) {} + + void startWatching(); + + /// On Haiku the watcher is ready when the ctor finished. + bool _ready = 1; + +private: + FolderWatcher *_parent; + + QString _folder; + + WatcherHandler *_handler; +}; +} diff --git a/src/gui/socketapi/socketapi.cpp b/src/gui/socketapi/socketapi.cpp index 1df11cf..a5cf142 100644 --- a/src/gui/socketapi/socketapi.cpp +++ b/src/gui/socketapi/socketapi.cpp @@ -265,7 +265,7 @@ SocketApi::SocketApi(QObject *parent) _system(QStringLiteral("pluginkit"), { QStringLiteral("-e"), QStringLiteral("use"), QStringLiteral("-i"), QStringLiteral(APPLICATION_REV_DOMAIN ".FinderSyncExt") }); #endif - } else if (Utility::isLinux() || Utility::isBSD()) { + } else if (Utility::isLinux() || Utility::isBSD() || Utility::isHaiku()) { QString runtimeDir; runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); socketPath = runtimeDir + "/" + Theme::instance()->appName() + "/socket"; diff --git a/src/gui/tray/Window.qml b/src/gui/tray/Window.qml index 75380d5..3d8fdc7 100644 --- a/src/gui/tray/Window.qml +++ b/src/gui/tray/Window.qml @@ -80,7 +80,7 @@ ApplicationWindow { } background: Rectangle { - radius: Systray.useNormalWindow ? 0.0 : Style.trayWindowRadius + // radius: Systray.useNormalWindow ? 0.0 : Style.trayWindowRadius border.width: Style.trayWindowBorderWidth border.color: palette.dark color: palette.window @@ -132,7 +132,7 @@ ApplicationWindow { } } - OpacityMask { +/* OpacityMask { anchors.fill: parent anchors.margins: Style.trayWindowBorderWidth source: ShaderEffectSource { @@ -145,7 +145,7 @@ ApplicationWindow { radius: Systray.useNormalWindow ? 0.0 : Style.trayWindowRadius } } - +*/ Drawer { id: userStatusDrawer width: parent.width diff --git a/src/libsync/filesystem.cpp b/src/libsync/filesystem.cpp index 7c58c7b..ff638e5 100644 --- a/src/libsync/filesystem.cpp +++ b/src/libsync/filesystem.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include "csync.h" #include "vio/csync_vio_local.h" @@ -74,7 +75,7 @@ bool FileSystem::setModTime(const QString &filename, time_t modTime) struct timeval times[2]; times[0].tv_sec = times[1].tv_sec = modTime; times[0].tv_usec = times[1].tv_usec = 0; - int rc = c_utimes(filename, times); + int rc = -1; // c_utimes(filename, times); if (rc != 0) { qCWarning(lcFileSystem) << "Error setting mtime for" << filename << "failed: rc" << rc << ", errno:" << errno; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 44396f2..63681d2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -93,7 +93,7 @@ else() nextcloud_build_test(E2eFileTransfer) endif() -if( UNIX AND NOT APPLE ) +if( UNIX AND NOT APPLE AND NOT HAIKU ) nextcloud_add_test(InotifyWatcher) endif(UNIX AND NOT APPLE) diff --git a/test/testfolderwatcher.cpp b/test/testfolderwatcher.cpp index d57358d..ccf19b6 100644 --- a/test/testfolderwatcher.cpp +++ b/test/testfolderwatcher.cpp @@ -264,7 +264,7 @@ private slots: } }; -#ifdef Q_OS_MAC +#ifdef Q_OS_HAIKU QTEST_MAIN(TestFolderWatcher) #else QTEST_GUILESS_MAIN(TestFolderWatcher) -- 2.42.1 From b27e014efb1059381077ba6960dc3bc2ed38cd44 Mon Sep 17 00:00:00 2001 From: Daniel Weber Date: Sun, 4 Feb 2024 00:09:35 +0100 Subject: Haiku not Apple diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index e81b1fe..5a01b92 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -320,7 +320,7 @@ ENDIF() IF( APPLE ) list(APPEND client_SRCS folderwatcher_mac.cpp) ENDIF() -IF( APPLE ) +IF( HAIKU ) list(APPEND client_SRCS folderwatcher_haiku.cpp) ENDIF() -- 2.42.1