1
0
mirror of https://github.com/clementine-player/Clementine synced 2024-12-16 19:31:02 +01:00

Add filesystem watcher using Mac FSEvents API.

(cherry picked from commit 96aa95bebd)
This commit is contained in:
John Maguire 2012-01-04 15:24:53 +00:00 committed by David Sansome
parent f1af27f849
commit 4a13d0ce29
3 changed files with 115 additions and 0 deletions

View File

@ -711,6 +711,7 @@ optional_source(APPLE
${GROWL}/Headers
${CMAKE_CURRENT_SOURCE_DIR}/../3rdparty/google-breakpad/client/mac/build/Release/Breakpad.framework
SOURCES
core/macfslistener.mm
core/macglobalshortcutbackend.mm
core/mac_startup.mm
devices/macdevicelister.mm
@ -720,6 +721,7 @@ optional_source(APPLE
widgets/maclineedit.mm
widgets/osd_mac.mm
HEADERS
core/macfslistener.h
core/macglobalshortcutbackend.h
devices/macdevicelister.h
ui/macscreensaver.h

38
src/core/macfslistener.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef MACFSLISTENER_H
#define MACFSLISTENER_H
#include <CoreServices/CoreServices.h>
#include <QObject>
#include <QSet>
class MacFSListener : public QObject {
Q_OBJECT
public:
MacFSListener();
void Init();
void AddPath(const QString& path);
signals:
void PathChanged(const QString& path);
private:
void UpdateStream();
static void EventStreamCallback(
ConstFSEventStreamRef stream,
void* user_data,
size_t num_events,
void* event_paths,
const FSEventStreamEventFlags event_flags[],
const FSEventStreamEventId event_ids[]);
CFRunLoopRef run_loop_;
FSEventStreamRef stream_;
QSet<QString> paths_;
};
#endif

75
src/core/macfslistener.mm Normal file
View File

@ -0,0 +1,75 @@
#include "macfslistener.h"
#include <CoreFoundation/CFArray.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSString.h>
#include "core/logging.h"
MacFSListener::MacFSListener()
: run_loop_(NULL),
stream_(NULL) {
}
void MacFSListener::Init() {
run_loop_ = CFRunLoopGetCurrent();
}
void MacFSListener::EventStreamCallback(
ConstFSEventStreamRef stream,
void* user_data,
size_t num_events,
void* event_paths,
const FSEventStreamEventFlags event_flags[],
const FSEventStreamEventId event_ids[]) {
MacFSListener* me = reinterpret_cast<MacFSListener*>(user_data);
char** paths = reinterpret_cast<char**>(event_paths);
for (int i = 0; i < num_events; ++i) {
QString path = QString::fromUtf8(paths[i]);
qLog(Debug) << "Something changed at:" << path;
emit me->PathChanged(path);
}
}
void MacFSListener::AddPath(const QString& path) {
paths_.insert(path);
UpdateStream();
}
void MacFSListener::UpdateStream() {
if (stream_) {
FSEventStreamInvalidate(stream_);
stream_ = NULL;
}
if (paths_.empty()) {
return;
}
NSMutableArray* array = [[NSMutableArray alloc] init];
foreach (const QString& path, paths_) {
NSString* string = [[NSString alloc] initWithUTF8String: path.toUtf8().constData()];
[array addObject: string];
[string release];
}
FSEventStreamContext context;
memset(&context, 0, sizeof(context));
context.info = this;
CFAbsoluteTime latency = 1.0;
stream_ = FSEventStreamCreate(
NULL,
&EventStreamCallback,
&context, // Copied
(CFArrayRef)array,
kFSEventStreamEventIdSinceNow,
latency,
kFSEventStreamCreateFlagNone);
FSEventStreamScheduleWithRunLoop(stream_, run_loop_, kCFRunLoopDefaultMode);
FSEventStreamStart(stream_);
[array release];
}