[vlc-commits] [Git][videolan/vlc][master] 3 commits: macosx: Remove bookmarked locations that no longer exist on load
Felix Paul Kühne (@fkuehne)
gitlab at videolan.org
Sat Feb 8 11:04:50 UTC 2025
Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
65cacb6e by Claudio Cambra at 2025-02-08T10:45:48+00:00
macosx: Remove bookmarked locations that no longer exist on load
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
3a034869 by Claudio Cambra at 2025-02-08T10:45:48+00:00
macosx: Observe changes to bookmarked locations and delete bookmark if location is deleted immediately
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
5923be34 by Claudio Cambra at 2025-02-08T10:45:48+00:00
macosx: Detect bookmark location rename and adjust the bookmark location rather than delete it
Signed-off-by: Claudio Cambra <developer at claudiocambra.com>
- - - - -
2 changed files:
- modules/gui/macosx/library/VLCLibrarySegment.m
- modules/gui/macosx/library/VLCLibraryWindowNavigationSidebarViewController.m
Changes:
=====================================
modules/gui/macosx/library/VLCLibrarySegment.m
=====================================
@@ -732,8 +732,13 @@ NSArray<NSString *> *defaultBookmarkedLocations()
const VLCLibrarySegmentType segmentType = VLCLibraryBrowseBookmarkedLocationSubSegmentType;
NSMutableArray<NSTreeNode *> * const bookmarkedLocationNodes = NSMutableArray.array;
+ NSMutableArray<NSString *> * const remainingBookmarkedLocations = bookmarkedLocations.mutableCopy;
for (NSString * const locationMrl in bookmarkedLocations) {
+ if (![NSFileManager.defaultManager fileExistsAtPath:[NSURL URLWithString:locationMrl].path]) {
+ [remainingBookmarkedLocations removeObject:locationMrl];
+ continue;
+ }
NSString * const locationName = locationMrl.lastPathComponent;
VLCLibrarySegmentBookmarkedLocation * const descriptor =
[[VLCLibrarySegmentBookmarkedLocation alloc] initWithSegmentType:segmentType
@@ -745,6 +750,10 @@ NSArray<NSString *> *defaultBookmarkedLocations()
}
self.internalChildNodes = bookmarkedLocationNodes.copy;
+
+ if (bookmarkedLocations.count != remainingBookmarkedLocations.count) {
+ [defaults setObject:remainingBookmarkedLocations forKey:VLCLibraryBookmarkedLocationsKey];
+ }
}
return self;
}
=====================================
modules/gui/macosx/library/VLCLibraryWindowNavigationSidebarViewController.m
=====================================
@@ -34,6 +34,11 @@
#import "views/VLCStatusNotifierView.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
// This needs to match whatever identifier has been set in the library window XIB
static NSString * const VLCLibrarySegmentCellIdentifier = @"VLCLibrarySegmentCellIdentifier";
@@ -41,6 +46,7 @@ static NSString * const VLCLibrarySegmentCellIdentifier = @"VLCLibrarySegmentCel
@property BOOL ignoreSegmentSelectionChanges;
@property (readonly) NSEdgeInsets scrollViewInsets;
+ at property (readonly) NSMutableDictionary<NSString *, dispatch_source_t> *observedPathDispatchSources;
@end
@@ -53,6 +59,7 @@ static NSString * const VLCLibrarySegmentCellIdentifier = @"VLCLibrarySegmentCel
_libraryWindow = libraryWindow;
_segments = VLCLibrarySegment.librarySegments;
_ignoreSegmentSelectionChanges = NO;
+ _observedPathDispatchSources = NSMutableDictionary.dictionary;
}
return self;
}
@@ -134,6 +141,76 @@ static NSString * const VLCLibrarySegmentCellIdentifier = @"VLCLibrarySegmentCel
byExtendingSelection:NO];
self.ignoreSegmentSelectionChanges = NO;
+
+ [self updateBookmarkObservation];
+}
+
+- (void)updateBookmarkObservation
+{
+ NSUserDefaults * const defaults = NSUserDefaults.standardUserDefaults;
+ NSArray<NSString *> * const bookmarkedLocations =
+ [defaults stringArrayForKey:VLCLibraryBookmarkedLocationsKey];
+ if (bookmarkedLocations.count == 0) {
+ return;
+ }
+
+ NSMutableArray<NSString *> * const deletedLocations = self.observedPathDispatchSources.allKeys.mutableCopy;
+ const __weak typeof(self) weakSelf = self;
+
+ for (NSString * const locationMrl in bookmarkedLocations) {
+ [deletedLocations removeObject:locationMrl];
+ if ([self.observedPathDispatchSources objectForKey:locationMrl] != nil) {
+ continue;
+ }
+ NSURL * const locationUrl = [NSURL URLWithString:locationMrl];
+ const uintptr_t descriptor = open(locationUrl.path.UTF8String, O_EVTONLY);
+ if (descriptor == -1) {
+ continue;
+ }
+ struct stat fileStat;
+ const int statResult = fstat(descriptor, &fileStat);
+
+ const dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+ const dispatch_source_t fileDispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, descriptor, DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME, globalQueue);
+ dispatch_source_set_event_handler(fileDispatchSource, ^{
+ const unsigned long eventFlags = dispatch_source_get_data(fileDispatchSource);
+ if (eventFlags & DISPATCH_VNODE_RENAME && statResult != -1) {
+ NSURL * const parentLocationUrl = locationUrl.URLByDeletingLastPathComponent;
+ NSString * const parentLocationPath = parentLocationUrl.path;
+ NSArray<NSString *> * const files = [NSFileManager.defaultManager contentsOfDirectoryAtPath:parentLocationPath error:nil];
+ NSString *newFileName = nil;
+
+ for (NSString * const file in files) {
+ NSString * const fullChildPath = [parentLocationPath stringByAppendingPathComponent:file];
+ struct stat currentFileStat;
+ if (stat(fullChildPath.UTF8String, ¤tFileStat) == -1) {
+ continue;
+ } else if (currentFileStat.st_ino == fileStat.st_ino) {
+ newFileName = fullChildPath.lastPathComponent;
+ break;
+ }
+ }
+
+ if (newFileName != nil) {
+ NSMutableArray<NSString *> * const mutableBookmarkedLocations = bookmarkedLocations.mutableCopy;
+ const NSUInteger locationIndex = [mutableBookmarkedLocations indexOfObject:locationMrl];
+ NSString * const newLocationMrl = [parentLocationUrl URLByAppendingPathComponent:newFileName].absoluteString;
+ [mutableBookmarkedLocations replaceObjectAtIndex:locationIndex withObject:newLocationMrl];
+ [defaults setObject:mutableBookmarkedLocations forKey:VLCLibraryBookmarkedLocationsKey];
+ }
+ }
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [weakSelf internalNodesChanged:nil];
+ });
+ });
+ dispatch_source_set_cancel_handler(fileDispatchSource, ^{
+ close(descriptor);
+ });
+ dispatch_resume(fileDispatchSource);
+ [self.observedPathDispatchSources setObject:fileDispatchSource forKey:locationMrl];
+ }
+
+ [self.observedPathDispatchSources removeObjectsForKeys:deletedLocations];
}
- (void)statusViewActivated:(NSNotification *)notification
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4d225c66e678656bd0b50f1461a452d4bfc5fe65...5923be34f415c13b045066cf0135dd0f5e0beb21
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4d225c66e678656bd0b50f1461a452d4bfc5fe65...5923be34f415c13b045066cf0135dd0f5e0beb21
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list