Revision: 15137 http://sourceforge.net/p/skim-app/code/15137 Author: hofman Date: 2025-05-01 21:43:56 +0000 (Thu, 01 May 2025) Log Message: ----------- Generate the image for an image tooltip async. Cancel showing when another image is generated or the tooltip is removed while generating.
Modified Paths: -------------- trunk/SKImageToolTipWindow.h trunk/SKImageToolTipWindow.m Modified: trunk/SKImageToolTipWindow.h =================================================================== --- trunk/SKImageToolTipWindow.h 2025-04-22 09:07:28 UTC (rev 15136) +++ trunk/SKImageToolTipWindow.h 2025-05-01 21:43:56 UTC (rev 15137) @@ -47,6 +47,8 @@ NSPoint point; CGFloat scale; NSImageView *imageView; + NSInteger currentRequest; + BOOL generatingRequest; } @property (class, nonatomic, readonly) SKImageToolTipWindow *sharedToolTipWindow; Modified: trunk/SKImageToolTipWindow.m =================================================================== --- trunk/SKImageToolTipWindow.m 2025-04-22 09:07:28 UTC (rev 15136) +++ trunk/SKImageToolTipWindow.m 2025-05-01 21:43:56 UTC (rev 15137) @@ -99,7 +99,21 @@ return self; } ++ (dispatch_queue_t)imageQueue { + static dispatch_queue_t imageQueue = nil; + if (imageQueue == nil) { + dispatch_queue_attr_t queuePriority = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_DEFAULT, 0); + imageQueue = dispatch_queue_create("net.sourceforge.skim-app.skim.thumbnails.default", queuePriority); + } + return imageQueue; +} + - (void)orderOut:(id)sender { + // ignore any currently generating image + if (generatingRequest) { + ++currentRequest; + generatingRequest = NO; + } context = nil; point = NSZeroPoint; [super orderOut:sender]; @@ -106,6 +120,11 @@ } - (void)fadeOut { + // ignore any currently generating image + if (generatingRequest) { + ++currentRequest; + generatingRequest = NO; + } context = nil; point = NSZeroPoint; [super fadeOut]; @@ -112,36 +131,53 @@ } - (void)showDelayed { - NSNumber *usedScaleNumber = [[NSUserDefaults standardUserDefaults] objectForKey:SKToolTipScaleKey]; - CGFloat usedScale = [usedScaleNumber respondsToSelector:@selector(doubleValue)] ? [usedScaleNumber doubleValue] : DEFAULT_SCALE; + if (generatingRequest) + ++currentRequest; + generatingRequest = YES; + + NSInteger myRequest =currentRequest; NSPoint thePoint = NSEqualPoints(point, NSZeroPoint) ? [NSEvent mouseLocation] : point; - NSRect contentRect = NSZeroRect, screenRect = [[NSScreen screenForPoint:thePoint] frame]; - NSImage *image = [context toolTipImageWithScale:usedScale > 0.0 ? usedScale : usedScale < 0.0 ? fmin(scale, -usedScale) : scale]; - BOOL isOpaque = [[[image representations] firstObject] isOpaque]; + NSRect screenRect = [[NSScreen screenForPoint:thePoint] frame]; - if (image) { - [imageView setImage:image]; + dispatch_async([[self class] imageQueue], ^{ - [[self contentView] setContentFilters:isOpaque ? SKColorEffectFilters() : @[]]; + NSNumber *usedScaleNumber = [[NSUserDefaults standardUserDefaults] objectForKey:SKToolTipScaleKey]; + CGFloat usedScale = [usedScaleNumber respondsToSelector:@selector(doubleValue)] ? [usedScaleNumber doubleValue] : DEFAULT_SCALE; + NSImage *image = [context toolTipImageWithScale:usedScale > 0.0 ? usedScale : usedScale < 0.0 ? fmin(scale, -usedScale) : scale]; - contentRect.size = [image size]; - contentRect.origin.x = fmin(thePoint.x, NSMaxX(screenRect) - NSWidth(contentRect)); - contentRect.origin.y = thePoint.y - WINDOW_OFFSET - NSHeight(contentRect); - contentRect = [self frameRectForContentRect:contentRect]; - if (NSMinY(contentRect) < NSMinX(screenRect)) - contentRect.origin.y = thePoint.y + WINDOW_OFFSET; - [self setFrame:contentRect display:NO]; - - if ([self isVisible] && [self alphaValue] > CRITICAL_ALPHA_VALUE) - [self orderFront:self]; - else - [self fadeIn]; - - } else { - - [self fadeOut]; - - } + dispatch_async(dispatch_get_main_queue(), ^{ + // check if another image is enerated or we are fading out + if (myRequest != currentRequest) + return; + generatingRequest = NO; + + if (image) { + BOOL isOpaque = [[[image representations] firstObject] isOpaque]; + [imageView setImage:image]; + + [[self contentView] setContentFilters:isOpaque ? SKColorEffectFilters() : @[]]; + + NSRect contentRect = NSZeroRect; + contentRect.size = [image size]; + contentRect.origin.x = fmin(thePoint.x, NSMaxX(screenRect) - NSWidth(contentRect)); + contentRect.origin.y = thePoint.y - WINDOW_OFFSET - NSHeight(contentRect); + contentRect = [self frameRectForContentRect:contentRect]; + if (NSMinY(contentRect) < NSMinX(screenRect)) + contentRect.origin.y = thePoint.y + WINDOW_OFFSET; + [self setFrame:contentRect display:NO]; + + if ([self isVisible] && [self alphaValue] > CRITICAL_ALPHA_VALUE) + [self orderFront:self]; + else + [self fadeIn]; + + } else { + + [self fadeOut]; + + } + }); + }); } - (void)stopAnimation { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ Skim-app-commit mailing list Skim-app-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/skim-app-commit