A bit late to the party, but I just installed Big Sur on my laptop. Running my app there, I notice that my dock icon annotation appears microscopic. Is this because it still uses the old dock icons that were OK on Mojave? I never made any progress on changing that.
Thanks, I went that route. And running with a new .icns file for the app’s icons works as before on Mojave. But under Big Sur, my dock icon annotation is still microscopic.
And under Big Sur, can’t the IDE delete the debug app after the app terminates? I’m using remote debugging, with 2020r1.1 under Mojave.
Dock animation is working fine here on Monterey. But AFAIR I had to change some code. Resetting the dock is buggy.
Here’s my code to update the icon with a red disk with a count in it. The disk is supposed to be in the top righthand corner:
// Sets the app Dock icon based on the current count of unread mails. #if (TargetMacOS=True) then Var iconPtr as DockItem, graphic As Graphics, mystr As String, x, y As Integer iconPtr = App.DockItem graphic = iconPtr.Graphics iconPtr.ResetIcon () graphic.DrawPicture (ilettericon, 0, 0, 512, 512) iconPtr.UpdateNow () if (unreadCount=0) then Return graphic.DrawingColor = &cff0000 graphic.FillOval (280, 10, 220, 220) if (unreadCount>99) Then graphic.FontSize = 330 x = 330 y = 300 mystr = "*" ElseIf (unreadCount>9) Then graphic.FillOval (230, 10, 220, 220) graphic.FontSize = 172 x = 275 y = 180 mystr = unreadCount.ToString Else graphic.FontSize = 172 x = 345 y = 180 mystr = unreadCount.ToString end if graphic.DrawingColor = &cffffff graphic.FontName = "Helvetica" graphic.FontUnit = FontUnits.Point graphic.Bold = True graphic.DrawText (mystr, x, y) iconPtr.UpdateNow () Return #endif
This code worked as expected under Mojave with a full-size rectangular 512x512 icon. Now, with the smaller masked-off icons, surrounded by a transparent area, we see:
Under Mojave, the red oval is drawn in the right place at the right size. However, ResetIcon() appears to do nothing, so if
unreadCount=0then I’m left with a red rising sun behind the right shoulder of the icon.
Under Big Sur it’s more bizarre. The same thing is drawn, same behaviour, but as a perhaps 4x4 image (still at 0, 0) rather than full-size. So the icon has a small pixel-pixie on its left shoulder.
Couple of minor points that I can see:
- DockItem.Reset doesn’t work (feedback://showreport?report_id=63498).
- I’m not using a fixed font but a multiple of 128.
Here is my partial code for the dock badge (screenshot above is for the animation):
dim DockGraphics as Graphics = app.DockItem.Graphics if DockGraphics = Nil then Return dim MainPicture as new Picture(DockGraphics.Width, DockGraphics.Width, 32) const FontSize as Integer = 28 const BaseOffSet as Integer = 14 const BaseArc as Integer = 20 'set up data for picture dim ScaleFactor as Integer = DockGraphics.Width/128 dim theGraphics as Graphics = MainPicture.Graphics theGraphics.FontSize = FontSize * ScaleFactor dim theWidth as Integer = theGraphics.TextWidth(str(NoOfMailsAdded)) theWidth = Max(theWidth, MaxWidth) MaxWidth = theWidth dim theHeight as Integer = theGraphics.TextHeight(str(NoOfMailsAdded), 10000) dim Offset as Integer = BaseOffSet * ScaleFactor dim PictureOffset as Integer = MainPicture.Height - theWidth - Offset dim theArc as Integer = BaseArc * ScaleFactor 'draw main picture 'draw background FillRectangleGradient(theGraphics, 0, 0, theGraphics.Width, Offset + theHeight, Color.RGB(137, 22, 27), Color.RGB(184, 44, 35)) 'draw number theGraphics.DrawingColor = Color.RGB(255, 255, 255) theGraphics.DrawText(str(NoOfMailsAdded), PictureOffset + Offset/2, Offset/2 + theGraphics.FontAscent) 'draw border theGraphics.DrawingColor = Color.RGB(117, 0, 19) theGraphics.PenSize = 2 * ScaleFactor theGraphics.DrawRoundRectangle(PictureOffset, 0, Offset + theWidth, Offset + theHeight, theArc, theArc)
The full code example is attached to the Feedback case.
I wouldn’t assume that the size will be 512. Since the dawn of retina, the max size is actually 1024 and could certainly change again in the future if Apple decides to have a 3x display like on iOS.
You could just make a multiplier like this:
Var scaleFactor as double = g.width / 512
And then multiply by that number for any sizes that you need, including text.
Don’t draw your own badge.
Thank you for that, @Beatrix_Willius . I didn’t study it completely but it pointed me to a couple of things such as
ClearRectangle(), and as a result, the code that was:
iconPtr = App.DockItem graphic = iconPtr.Graphics iconPtr.ResetIcon () graphic.DrawPicture (ilettericon, 0, 0, 512, 512) iconPtr.UpdateNow () if (unreadCount=0) then Return
iconPtr = App.DockItem graphic = iconPtr.Graphics icon = new Picture (graphic.Width, graphic.Width, 32) icon = iLettericon graphic.ClearRectangle (0, 0, graphic.Width, graphic.Width) graphic.DrawPicture (icon, 0, 0, graphic.Width, graphic.Width) iconPtr.UpdateNow () if (unreadCount=0) then Return
and this gives the right behaviour under Mojave, with the new style icon. Under Big Sur, as soon as this method is called. I think the drawing that is done is correct, but the icon that’s drawn is only a few pixels (perhaps 16) high and wide. That replaces the normal dock icon until the app quits, So there’s a scaling issue, presumably.
What is the third parameter (32) for
new Picture ?
Seriously… stop drawing it yourself. The system provides you the right way to do this. It’ll scale the badge separately from your icon so it always looks right and you don’t have to futz around with making it work.
Declare Function NSClassFromString Lib "Foundation" (className As CFStringRef) As Ptr Var NSApp As Ptr = NSClassFromString("NSApplication") Declare Function SharedApplication Lib "Foundation" Selector "sharedApplication" (receiver As Ptr) As Ptr Var SharedApp As Ptr = SharedApplication(NSApp) Declare Function DockTile Lib "Foundation" Selector "dockTile" (receiver As Ptr) As Ptr Var Tile As Ptr = DockTile(SharedApp) Declare Sub SetBadge Lib "Foundation" Selector "setBadgeLabel:" (receiver As Ptr, label As CFStringRef) SetBadge(Tile, "3")
You’re also doing absolutely nothing on the first line since you’re creating a new picture to match the size of the graphics object, then immediately throwing it away. On the next lines you’re scaling iLettericon to fill the
But just throw out all this code and let the system manage your application icon and badge unless you’re trying to change the actual icon. Even if you’re changing the icon at runtime, don’t draw the badge.
OK, I’ll give it a try. But not tonight, it’s nearly midnght. Time for a few pages of Agatha Christie.
I have to say that the picture code did look odd, but I’ve been battling a number of issues today.
I’ve tested your declares now in Mojave and BS and it works as advertised, so thanks for that; I see that a blank string makes the badge go away, (as I’d hoped). My only question is, is there a way to make the badge’s text be bold? That would make it slightly more readable.
Funnily enough, my original code only worked under Mojave because as luck would have it I only had one icon for the app (at 512x512). Once I included a full set (from Iconographer Mini), my badge, which was displaying small under BS, started doing the same under Mojave.
Any way to change the background colour (or any font property) in this code?
No. I’d imagine since it is system-supplied that it obeys accessibility settings. So if the user’s system wants bolder text, I’d expect this badge to be bolder too. It’s not what you’re looking for, but Apple doesn’t give you options.
Same basic reply. All you can tell the system is what the badge should say. Everything else is handled for you. So if the user has colorblind options enabled, high contrast mode enabled, Apple moves the badge, makes it blink, turns it upside down, or any other crazy idea, your app will instantly match.
So if you want to notify in a non-red colour (for instance), the custom way is still mandatory.
I’d argue you shouldn’t be doing it. Go with what the user knows and expects.
For most other UI things, I’d agree. Here, red is normally a “warning” icon. I can imagine times where this isn’t appropriate (and I hate red, personally…).
Sure, but in this case it isn’t. This is the color Apple chose for its badge. It’s what the user expects.
Oh… that’s interesting and too bad