Skip to content

Commit 1f0a17a

Browse files
committed
various bug fixes and small improvements for version 2.2.2 (2023-08-17)
1 parent fa470ee commit 1f0a17a

34 files changed

+838
-159
lines changed

AppKitAdditions/PGAppKitAdditions.m

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,14 @@ - (NSColor *)PG_checkerboardPatternColor
120120
}
121121
- (NSColor *)PG_patternColorWithImage:(NSImage *)image fraction:(CGFloat)fraction
122122
{
123+
assert(image);
123124
NSSize const s = [image size];
124125
NSRect const r = (NSRect){NSZeroPoint, s};
125126
NSImage *const pattern = [[[NSImage alloc] initWithSize:s] autorelease];
126127
[pattern lockFocus];
127-
[self set];
128-
NSRectFill(r);
129-
[image drawInRect:r fromRect:NSZeroRect operation:NSCompositingOperationSourceAtop fraction:fraction];
128+
[self set];
129+
NSRectFill(r);
130+
[image drawInRect:r fromRect:NSZeroRect operation:NSCompositingOperationSourceAtop fraction:fraction];
130131
[pattern unlockFocus];
131132
return [NSColor colorWithPatternImage:pattern];
132133
}

Controllers/PGBookmarkController.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
3434
IBOutlet NSMenu *bookmarkMenu;
3535
IBOutlet NSMenuItem *emptyMenuItem;
3636
BOOL _deletesBookmarks;
37-
NSMutableArray *_bookmarks;
37+
NSMutableArray<PGBookmark*> *_bookmarks;
3838
}
3939

4040
+ (id)sharedBookmarkController;

Controllers/PGBookmarkController.m

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,16 @@
3636
#import "PGAppKitAdditions.h"
3737
#import "PGFoundationAdditions.h"
3838

39-
static NSString *const PGPausedDocumentsKey = @"PGPausedDocuments4"; // file-ref is NSURL (not AliasHandle)
39+
// 2023/08/12 the paused document data blob is too large for NSUserDefaults in macOS 12 Monterey:
40+
// "Sequential [User Defaults] CFPrefsPlistSource (Domain: com.SequentialX.Sequential,
41+
// User: kCFPreferencesCurrentUser, ByHost: No, Container: (null), Contents Need Refresh: Yes):
42+
// Attempting to store >= 4194304 bytes of data in CFPreferences/NSUserDefaults on this platform
43+
// is invalid. This is a bug in Sequential or a library it uses."
44+
//
45+
// Solution: store this data in a separate file in the Application Support folder instead of in
46+
// the app's UserDefaults object.
47+
static NSString *const PGPausedDocumentsFileName = @"PausedDocuments.plist";
48+
//static NSString *const PGPausedDocumentsKey = @"PGPausedDocuments4"; // file-ref is NSURL (not AliasHandle)
4049
#if 0
4150
static NSString *const PGPausedDocumentsDeprecated3Key = @"PGPausedDocuments3"; // Deprecated after 2.1.2.
4251
static NSString *const PGPausedDocumentsDeprecated2Key = @"PGPausedDocuments2"; // Deprecated after 1.3.2.
@@ -53,6 +62,42 @@ static OSStatus PGBookmarkControllerFlagsChanged(EventHandlerCallRef inHandlerCa
5362
}
5463
#endif
5564

65+
static
66+
NSURL*
67+
GetBookmarksFileURL(BOOL createParentFolderIfNonExistant) {
68+
NSFileManager* fileMgr = NSFileManager.defaultManager;
69+
NSArray<NSURL*>* urls = [fileMgr URLsForDirectory:NSApplicationSupportDirectory
70+
inDomains:NSUserDomainMask];
71+
if (nil == urls || 1 != urls.count)
72+
return nil;
73+
74+
NSURL* parentFolder = [[urls objectAtIndex:0] URLByAppendingPathComponent:NSBundle.mainBundle.bundleIdentifier
75+
isDirectory:YES];
76+
if (nil == parentFolder)
77+
return nil;
78+
NSError* error = nil;
79+
BOOL b = createParentFolderIfNonExistant ?
80+
[fileMgr createDirectoryAtURL:parentFolder
81+
withIntermediateDirectories:NO
82+
attributes:nil
83+
error:&error] : YES;
84+
//if (!b) NSLog(@"error %@", error);
85+
if (!b) {
86+
if (!error || !error.userInfo)
87+
return nil;
88+
89+
id ue = [error.userInfo objectForKey:NSUnderlyingErrorKey];
90+
if (!ue || ![ue isKindOfClass:NSError.class])
91+
return nil;
92+
93+
error = (NSError*) ue;
94+
if (NSPOSIXErrorDomain != error.domain || EEXIST != error.code)
95+
return nil;
96+
}
97+
98+
return [parentFolder URLByAppendingPathComponent:PGPausedDocumentsFileName isDirectory:NO];
99+
}
100+
56101
@interface PGBookmarkController(Private)
57102

58103
- (void)_updateMenuItemForBookmark:(PGBookmark *)aBookmark;
@@ -177,9 +222,21 @@ - (void)_removeBookmarkAtIndex:(NSUInteger)index
177222
[bookmarkMenu removeItemAtIndex:[bookmarkMenu numberOfItems] - index - 1];
178223
if(![_bookmarks count]) [bookmarkMenu addItem:emptyMenuItem];
179224
}
225+
180226
- (void)_saveBookmarks
181227
{
182-
#if 1 // 2021/07/21 modernized
228+
#if 1 // 2023/08/12 now saved to a separate file instead of NSUserDefaults (because it generates too-much-data warnings)
229+
NSError* error = nil;
230+
NSData* archivedBookmarks = [NSKeyedArchiver archivedDataWithRootObject:_bookmarks
231+
requiringSecureCoding:YES
232+
error:&error];
233+
if (nil == archivedBookmarks || nil != error)
234+
return;
235+
236+
NSURL* url = GetBookmarksFileURL(YES);
237+
//NSLog(@"%@ url = %@", PGPausedDocumentsFileName, url);
238+
(void) [archivedBookmarks writeToURL:url options:NSDataWritingAtomic error:&error];
239+
#elif 1 // 2021/07/21 modernized
183240
/* {
184241
NSError* error = nil;
185242
NSData* d = [NSKeyedArchiver archivedDataWithRootObject:NSUserDefaults.standardUserDefaults.dictionaryRepresentation
@@ -228,13 +285,33 @@ - (id)init
228285
InstallEventHandler(GetUserFocusEventTarget(), PGBookmarkControllerFlagsChanged, 2, list, self, NULL);
229286
#endif
230287
}
288+
289+
#if 1 // 2023/08/12 now saved to a separate file instead of NSUserDefaults (because it generates too-much-data warnings)
290+
NSURL* url = GetBookmarksFileURL(NO);
291+
//NSLog(@"%@ url = %@", PGPausedDocumentsFileName, url);
292+
NSError* error = nil;
293+
NSData* bookmarksData = [NSData dataWithContentsOfURL:url options:0 error:&error];
294+
#else
231295
NSUserDefaults *const defaults = [NSUserDefaults standardUserDefaults];
232296
NSData *bookmarksData = [defaults objectForKey:PGPausedDocumentsKey];
297+
#endif
298+
233299
BOOL bookmarksDataIsFromPGPausedDocumentsKey = nil != bookmarksData;
300+
301+
// 2023/08/12 transfer list of paused documents from UserDefaults to separate file
302+
if (!bookmarksDataIsFromPGPausedDocumentsKey) {
303+
bookmarksData = [NSUserDefaults.standardUserDefaults objectForKey:@"PGPausedDocuments4"];
304+
if (nil != bookmarksData) {
305+
[NSUserDefaults.standardUserDefaults removeObjectForKey:@"PGPausedDocuments4"];
306+
[NSUserDefaults.standardUserDefaults synchronize];
307+
}
308+
}
309+
234310
#if 1 // 2021/07/21 modernized
235311
if(bookmarksData) {
236312
NSError* error = nil;
237313
NSSet* classes = [NSSet setWithArray:@[[NSMutableArray class], [PGBookmark class]]];
314+
// NSSet* classes = [NSSet setWithArray:@[[NSData class], [NSMutableArray class], [PGBookmark class]]];
238315
_bookmarks = [[NSKeyedUnarchiver unarchivedObjectOfClasses:classes
239316
fromData:bookmarksData
240317
error:&error] retain];

Controllers/PGDisplayController.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ PGClipViewDelegate, PGDocumentWindowDelegate>
9797
- (IBAction)hideFindPanel:(id)sender;
9898

9999
- (IBAction)toggleFullscreen:(id)sender;
100+
- (IBAction)toggleEntireScreenWhenInFullScreen:(id)sender;
100101
- (IBAction)toggleInfo:(id)sender;
101102
- (IBAction)toggleThumbnails:(id)sender;
102103
- (IBAction)changeReadingDirection:(id)sender;

Controllers/PGDisplayController.m

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ static inline NSSize PGConstrainSize(NSSize min, NSSize size, NSSize max)
7878

7979
@interface PGDisplayController(Private)
8080

81+
- (void)_setClipViewBackground;
8182
- (void)_setImageView:(PGImageView *)aView;
8283
- (BOOL)_setActiveNode:(PGNode *)aNode;
8384
- (void)_readActiveNode;
@@ -228,11 +229,23 @@ - (IBAction)hideFindPanel:(id)sender
228229
- (IBAction)toggleFullscreen:(id)sender
229230
{
230231
[[PGDocumentController sharedDocumentController] setFullscreen:![PGDocumentController sharedDocumentController].fullscreen];
232+
233+
// 2023/08/14 the background color now depends on whether the view's window
234+
// is in fullscreen mode so the background color must be updated:
235+
[self _setClipViewBackground];
236+
}
237+
238+
- (IBAction)toggleEntireScreenWhenInFullScreen:(id)sender // 2023/08/14 added
239+
{
240+
PGDocumentController* dc = PGDocumentController.sharedDocumentController;
241+
dc.usesEntireScreenWhenInFullScreen = !dc.usesEntireScreenWhenInFullScreen;
231242
}
243+
232244
- (IBAction)toggleInfo:(id)sender
233245
{
234246
[[self activeDocument] setShowsInfo:![[self activeDocument] showsInfo]];
235247
}
248+
236249
- (IBAction)toggleThumbnails:(id)sender
237250
{
238251
[[self activeDocument] setShowsThumbnails:![[self activeDocument] showsThumbnails]];
@@ -856,13 +869,31 @@ - (void)thumbnailControllerContentInsetDidChange:(NSNotification *)aNotif
856869
[w setMinSize:minSize];
857870
// NSEnableScreenUpdates(); 2021/07/21 deprecated
858871
}
872+
859873
- (void)prefControllerBackgroundPatternColorDidChange:(NSNotification *)aNotif;
860874
{
861-
[clipView setBackgroundColor:[[PGPreferenceWindowController sharedPrefController] backgroundPatternColor]];
875+
[self _setClipViewBackground];
876+
}
877+
878+
- (void)prefControllerBackgroundColorUsedInFullScreenDidChange:(NSNotification *)aNotif;
879+
{
880+
if (PGDocumentController.sharedDocumentController.fullscreen)
881+
[self _setClipViewBackground]; // updates only when in fullscreen mode
862882
}
863883

864884
#pragma mark -PGDisplayController(Private)
865885

886+
- (void)_setClipViewBackground {
887+
// 2023/08/14 added this method to enable the background color to depend on
888+
// whether the view's window is in fullscreen mode and whether user wants it
889+
// used in fullscreen mode.
890+
if (PGDocumentController.sharedDocumentController.fullscreen &&
891+
![NSUserDefaults.standardUserDefaults boolForKey:PGBackgroundColorUsedInFullScreenKey])
892+
[clipView setBackgroundColor:NSColor.blackColor];
893+
else
894+
[clipView setBackgroundColor:[PGPreferenceWindowController.sharedPrefController backgroundPatternColor]];
895+
}
896+
866897
- (void)_setImageView:(PGImageView *)aView
867898
{
868899
if(aView == _imageView) return;
@@ -1055,6 +1086,7 @@ - (id)init
10551086
[self _updateInfoPanelText];
10561087

10571088
[[PGPreferenceWindowController sharedPrefController] PG_addObserver:self selector:@selector(prefControllerBackgroundPatternColorDidChange:) name:PGPreferenceWindowControllerBackgroundPatternColorDidChangeNotification];
1089+
[[PGPreferenceWindowController sharedPrefController] PG_addObserver:self selector:@selector(prefControllerBackgroundColorUsedInFullScreenDidChange:) name:PGPreferenceWindowControllerBackgroundColorUsedInFullScreenDidChangeNotification];
10581090
[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:PGImageScaleConstraintKey options:kNilOptions context:NULL];
10591091
}
10601092
return self;
@@ -1112,6 +1144,11 @@ - (BOOL)validateMenuItem:(NSMenuItem *)anItem
11121144

11131145
// View:
11141146
if(@selector(toggleFullscreen:) == action) [anItem setTitle:NSLocalizedString(([[PGDocumentController sharedDocumentController] isFullscreen] ? @"Exit Full Screen" : @"Enter Full Screen"), @"Enter/exit full screen. Two states of the same item.")];
1147+
if(@selector(toggleEntireScreenWhenInFullScreen:) == action) { // 2023/08/14 added
1148+
[anItem setState:PGDocumentController.sharedDocumentController.usesEntireScreenWhenInFullScreen];
1149+
// this menu item is only enabled when the window is in full screen mode
1150+
return PGDocumentController.sharedDocumentController.fullscreen;
1151+
}
11151152
if(@selector(toggleInfo:) == action) [anItem setTitle:NSLocalizedString(([[self activeDocument] showsInfo] ? @"Hide Info" : @"Show Info"), @"Lets the user toggle the on-screen display. Two states of the same item.")];
11161153
if(@selector(toggleThumbnails:) == action) [anItem setTitle:NSLocalizedString(([[self activeDocument] showsThumbnails] ? @"Hide Thumbnails" : @"Show Thumbnails"), @"Lets the user toggle whether thumbnails are shown. Two states of the same item.")];
11171154
if(@selector(changeReadingDirection:) == action) [anItem setState:[[self activeDocument] readingDirection] == tag];

Controllers/PGDocumentController.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
3636
@class PGActivityPanelController;
3737

3838
extern NSString *const PGAntialiasWhenUpscalingKey;
39+
extern NSString *const PGBackgroundColorSourceKey; // 2023/08/17
3940
extern NSString *const PGBackgroundColorKey;
4041
extern NSString *const PGBackgroundPatternKey;
42+
extern NSString *const PGBackgroundColorUsedInFullScreenKey; // 2023/08/14
4143
extern NSString *const PGMouseClickActionKey;
4244
extern NSString *const PGEscapeKeyMappingKey;
4345
extern NSString *const PGDimOtherScreensKey;
@@ -131,6 +133,8 @@ typedef NSUInteger PGImageScaleConstraint;
131133
@property(readonly) PGDisplayController *displayControllerForNewDocument;
132134
@property(assign, nonatomic, getter = isFullscreen) BOOL fullscreen;
133135
@property(readonly) BOOL canToggleFullscreen;
136+
@property(assign, nonatomic) BOOL usesEntireScreenWhenInFullScreen; // 2023/08/14 added
137+
@property(readonly) BOOL canToggleUsesEntireScreenWhenInFullScreen; // 2023/08/14 added
134138
@property(readonly, copy) NSArray *documents;
135139
@property(readonly) NSMenu *scaleMenu;
136140
@property(readonly) NSSlider *scaleSlider;

Controllers/PGDocumentController.m

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@
5959
#import "PGZooming.h"
6060

6161
NSString *const PGAntialiasWhenUpscalingKey = @"PGAntialiasWhenUpscaling";
62+
NSString *const PGBackgroundColorSourceKey = @"PGBackgroundColorSource"; // 2023/08/17
6263
NSString *const PGBackgroundColorKey = @"PGBackgroundColor";
6364
NSString *const PGBackgroundPatternKey = @"PGBackgroundPattern";
65+
NSString *const PGBackgroundColorUsedInFullScreenKey = @"PGBackgroundColorUsedInFullScreen"; // 2023/08/14
6466
NSString *const PGMouseClickActionKey = @"PGMouseClickAction";
6567
NSString *const PGEscapeKeyMappingKey = @"PGEscapeKeyMapping";
6668
NSString *const PGDimOtherScreensKey = @"PGDimOtherScreens";
@@ -69,6 +71,7 @@
6971
NSString *const PGShowFileNameOnImageThumbnailKey = @"PGShowFileNameOnImageThumbnail";
7072
NSString *const PGShowCountsAndSizesOnContainerThumbnailKey = @"PGShowCountsAndSizesOnContainerThumbnail";
7173

74+
// TODO: work out if these can be removed
7275
static NSString *const PGRecentItemsKey = @"PGRecentItems2";
7376
static NSString *const PGRecentItemsDeprecated2Key = @"PGRecentItems"; // Deprecated after 1.3.2
7477
static NSString *const PGRecentItemsDeprecatedKey = @"PGRecentDocuments"; // Deprecated after 1.2.2.
@@ -110,7 +113,7 @@ + (void)initialize
110113
// [NSArchiver archivedDataWithRootObject:[NSColor blackColor]],
111114
[NSKeyedArchiver archivedDataWithRootObject:[NSColor blackColor] requiringSecureCoding:YES error:&error],
112115
PGBackgroundColorKey,
113-
[NSNumber numberWithUnsignedInteger:PGNoPattern], PGBackgroundPatternKey,
116+
[NSNumber numberWithUnsignedInteger:PGNoPattern], PGBackgroundPatternKey, // misnomer; should be PGBackgroundPatternTypeKey
114117
[NSNumber numberWithInteger:PGNextPreviousAction], PGMouseClickActionKey,
115118
[NSNumber numberWithUnsignedInteger:1], PGMaxDepthKey,
116119
@NO /* no */, PGFullscreenKey,
@@ -280,6 +283,7 @@ - (PGDisplayController *)displayControllerForNewDocument
280283
}
281284
return [[[PGWindowController alloc] init] autorelease];
282285
}
286+
283287
@synthesize fullscreen = _fullscreen;
284288
- (void)setFullscreen:(BOOL)flag
285289
{
@@ -288,12 +292,38 @@ - (void)setFullscreen:(BOOL)flag
288292
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:flag] forKey:PGFullscreenKey];
289293
[self _setFullscreen:flag];
290294
}
295+
291296
- (BOOL)canToggleFullscreen
292297
{
293298
if(_fullscreen) return YES;
294299
for(PGDocument *const doc in [self documents]) if([[[doc displayController] window] attachedSheet]) return NO;
295300
return YES;
296301
}
302+
303+
extern const NSString* const PGUseEntireScreenWhenInFullScreenKey;
304+
const NSString* const PGUseEntireScreenWhenInFullScreenKey = @"PGUseEntireScreenWhenInFullScreen";
305+
306+
- (BOOL) usesEntireScreenWhenInFullScreen
307+
{
308+
return [NSUserDefaults.standardUserDefaults
309+
boolForKey:(NSString*)PGUseEntireScreenWhenInFullScreenKey];
310+
}
311+
312+
- (void)setUsesEntireScreenWhenInFullScreen:(BOOL)flag // 2023/08/14 added
313+
{
314+
assert(_fullscreen && _fullscreenController);
315+
316+
[NSUserDefaults.standardUserDefaults setBool:flag
317+
forKey:(NSString*)PGUseEntireScreenWhenInFullScreenKey];
318+
319+
[_fullscreenController resizeToUseEntireScreen];
320+
}
321+
322+
- (BOOL)canToggleUsesEntireScreenWhenInFullScreen // 2023/08/14
323+
{
324+
return _fullscreen;
325+
}
326+
297327
@synthesize documents = _documents;
298328
- (NSMenu *)scaleMenu
299329
{
@@ -500,7 +530,7 @@ - (id)init
500530
NSArray* rdia = nil;
501531
if (recentItemsData) {
502532
NSError* error = nil;
503-
NSSet* classes = [NSSet setWithArray:@[[NSArray class], [PGResourceIdentifier class]]];
533+
NSSet* classes = [NSSet setWithArray:@[NSArray.class, NSData.class, PGResourceIdentifier.class]];
504534
rdia = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes
505535
fromData:recentItemsData
506536
error:&error];

Controllers/PGFullscreenController.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
3838

3939
- (void)displayScreenDidChange:(NSNotification *)aNotif;
4040

41+
- (void)resizeToUseEntireScreen; // 2023/08/14 added
42+
4143
@end

Controllers/PGFullscreenController.m

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ - (void)prepareToExitFullscreen
6464
[self _setMenuBarHidden:NO delayed:NO]; // For some reason, this moves windows downward slightly (at least on 10.5.3), so make sure it happens before our new windows get put onscreen.
6565
}
6666

67-
#pragma mark -
68-
6967
- (void)displayScreenDidChange:(NSNotification *)aNotif
7068
{
7169
NSScreen *const screen = [[PGPreferenceWindowController sharedPrefController] displayScreen];
@@ -74,6 +72,11 @@ - (void)displayScreenDidChange:(NSNotification *)aNotif
7472
[self _setMenuBarHidden:[NSScreen PG_mainScreen] == screen delayed:YES];
7573
}
7674

75+
- (void)resizeToUseEntireScreen // 2023/08/14 added
76+
{
77+
[(PGFullscreenWindow *)self.window resizeToUseEntireScreen];
78+
}
79+
7780
#pragma mark -PGFullscreenController(Private)
7881

7982
- (void)_setMenuBarHidden:(BOOL)hidden delayed:(BOOL)delayed
@@ -217,8 +220,7 @@ - (NSDragOperation)window:(PGDocumentWindow *)window dragOperationForInfo:(id<NS
217220
NSArray *const types = [pboard types];
218221
#if 1
219222
if([types containsObject:NSPasteboardTypeFileURL]) {
220-
NSArray *const paths = [pboard propertyListForType:NSPasteboardTypeFileURL];
221-
return [paths count] == 1 ? NSDragOperationGeneric : NSDragOperationNone;
223+
return NSDragOperationGeneric; // 2023/08/16 bugfix: no complex testing is now done
222224
} else if([types containsObject:NSPasteboardTypeURL]) {
223225
return [NSURL URLFromPasteboard:pboard] ? NSDragOperationGeneric : NSDragOperationNone;
224226
}

0 commit comments

Comments
 (0)