cocoansstatusitemnsstatusbar

Force NSStatusItem to Redraw


I create a NSStatusItem and add an image. After the image has been added, changing the image.template property has no immediate effect on the icon. Only after clicking the status item does the image become a template. Is there a way to force the system to redraw the status item/bar?

I put together the simple example, pressing the 'test' button changes the image to a template, but the change doesn't take effect until the status icon is selected.

-(void)awakeFromNib{
    // Setup status item
    statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
    statusMenu = [[NSMenu alloc] initWithTitle:@""];
    menuItem = [[NSMenuItem alloc] initWithTitle:@"test"
                                   action:nil
                                   keyEquivalent:@""];
    
    NSImage* img = [NSImage imageNamed:@"aubergine.png"];
    img.template = true;
    img.size = NSMakeSize(18.0, 18.0);
    statusItem.button.image = img;
    
    [statusItem setMenu:statusMenu];
    [statusMenu addItem:menuItem];

    // Add button to window
    NSButton* button = [[NSButton alloc] initWithFrame:NSMakeRect(10, 10, 50, 20)];
    [[window contentView] addSubview: button];
    [button setTitle: @"Test"];
    
    [button setTarget:self];
    [button setAction:@selector(buttonPressed)];
}

-(void)buttonPressed {
    [[[statusItem button] image] setTemplate: false];
}

Solution

  • As provided by Willeke in the comments, the solution is to use the needsDisplay property. The working function is:

    -(void)buttonPressed {
        [[[statusItem button] image] setTemplate: false];
        [[statusItem button] setNeedsDisplay: true];
    }