Position of NSStatusItem

  • Hey guys,
    is there a way to get the position of an NSStatusItem in the system's
    menubar? At the moment I use the following hack:

    @implementation NSStatusItem (Hack)
    - (NSRect)hackFrame
    {
    return [_fWindow frame];
    }
    @end

    But unfortunately I only get (-34.0, 0.0) as the position, which does
    not seem like screen-space coordinates :(

    Fabian
    nexUmoja.org
  • Hi Fabian,

    I'm currently working on an application, using a NSStatusItem with a
    custom view. With the following I can get the origin of the NSStatusItem

    NSRect rect = [[[statusItem view] window ] frame];

    Since I'm on a 24" iMac, the origin is about x=1525 y=1178

    I don't know if this works, if you don't use a custom view.

    regards
    Joachim

    Am 19.11.2007 um 23:14 schrieb [nexUmoja] Fabian Jäger:

    > Hey guys,
    > is there a way to get the position of an NSStatusItem in the
    > system's menubar? At the moment I use the following hack:
    >
    > @implementation NSStatusItem (Hack)
    > - (NSRect)hackFrame
    > {
    > return [_fWindow frame];
    > }
    > @end
    >
    > But unfortunately I only get (-34.0, 0.0) as the position, which
    > does not seem like screen-space coordinates :(
    >
    > Fabian
    > nexUmoja.org
  • Hi Fabian,

    since this is an international, english list, I think we should write
    english here. Even though my mother tongue is german too...

    You can't create a View for the StatusItem with that size: The max
    height of the MenuBar is 22px. So I thing creating a view with a
    height of 50 will fail.

    It's better to use the following:

    [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, [statusBarItem
    length], [[statusBarItem statusBar] thickness])]

    This takes the actual length of created StatusItem and the thickness
    of the MenuBar into account.

    Hope this helps

    Joachim

    Am 20.11.2007 um 22:40 schrieb [nexUmoja] Fabian Jäger:

    > Hallo Joachim,
    > erstmal danke für deinen Versuch mir zu helfen. Ich habe folgenden
    > Code:
    >
    > // instantiate statusbar-icon
    > NSStatusBar *systemBar = [NSStatusBar systemStatusBar];
    > theItem = [systemBar statusItemWithLength:
    > NSVariableStatusItemLength];
    > [theItem retain];
    > NSView *tmpView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0,
    > 50, 50)];
    > [theItem setView:tmpView];
    >
    > NSRect globalOrigin = [[[theItem view] window] frame];
    > NSLog(@"%f/%f", globalOrigin.origin.x, globalOrigin.origin.y);
    >
    > [theItem setView:nil];
    > [tmpView release];
    >
    > Leider bekomme ich immer x=-22 und y=0 als Ergebnis. Ich habe keine
    > Ahnung, woran das liegt :(
    >
    > Fabian
    >
    >
    > On 20.11.2007, at 22:11, Joachim Deelen wrote:
    >
    >> Hi Fabian,
    >>
    >> I'm currently working on an application, using a NSStatusItem with
    >> a custom view. With the following I can get the origin of the
    >> NSStatusItem
    >>
    >> NSRect rect = [[[statusItem view] window ] frame];
    >>
    >> Since I'm on a 24" iMac, the origin is about x=1525 y=1178
    >>
    >> I don't know if this works, if you don't use a custom view.
    >>
    >> regards
    >> Joachim
  • Now I use this code:

    // instantiate statusbar-icon
      NSStatusBar *systemBar = [NSStatusBar systemStatusBar];
              theItem = [systemBar statusItemWithLength:
    NSVariableStatusItemLength];
      [theItem retain];

      NSView *tmpView = [[NSView alloc] initWithFrame:NSMakeRect(0.0,
    0.0, [theItem length], [[theItem statusBar] thickness])];
      [theItem setView:tmpView];

      NSRect globalOrigin = [[[theItem view] window] frame];
      NSLog(@"%f/%f", globalOrigin.origin.x, globalOrigin.origin.y);

      [theItem setView:nil];
      [tmpView release];

    The output is: "0.000000/0.000000" ... don't really know what's wrong
    with the code :-(

    Fabian
    nexUmoja.org

    On 20.11.2007, at 22:57, Joachim Deelen wrote:

    > Hi Fabian,
    >
    > since this is an international, english list, I think we should
    > write english here. Even though my mother tongue is german too...
    >
    > You can't create a View for the StatusItem with that size: The max
    > height of the MenuBar is 22px. So I thing creating a view with a
    > height of 50 will fail.
    >
    > It's better to use the following:
    >
    > [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, [statusBarItem
    > length], [[statusBarItem statusBar] thickness])]
    >
    > This takes the actual length of created StatusItem and the
    > thickness of the MenuBar into account.
    >
    > Hope this helps
    >
    > Joachim
  • As far as I can see the only difference between your and my code is
    that I'm using a fixed length of the StatusItem instead of the
    NSVariableStatusItemLength.

    --
    Joachim

    Am 20.11.2007 um 23:03 schrieb [nexUmoja] Fabian Jäger:

    > Now I use this code:
    >
    > // instantiate statusbar-icon
    > NSStatusBar *systemBar = [NSStatusBar systemStatusBar];
    > theItem = [systemBar statusItemWithLength:
    > NSVariableStatusItemLength];
    > [theItem retain];
    >
    > NSView *tmpView = [[NSView alloc] initWithFrame:NSMakeRect(0.0,
    > 0.0, [theItem length], [[theItem statusBar] thickness])];
    > [theItem setView:tmpView];
    >
    > NSRect globalOrigin = [[[theItem view] window] frame];
    > NSLog(@"%f/%f", globalOrigin.origin.x, globalOrigin.origin.y);
    >
    > [theItem setView:nil];
    > [tmpView release];
    >
    > The output is: "0.000000/0.000000" ... don't really know what's
    > wrong with the code :-(
    >
    > Fabian
    > nexUmoja.org
    >
    >
    > On 20.11.2007, at 22:57, Joachim Deelen wrote:
    >
    >> Hi Fabian,
    >>
    >> since this is an international, english list, I think we should
    >> write english here. Even though my mother tongue is german too...
    >>
    >> You can't create a View for the StatusItem with that size: The max
    >> height of the MenuBar is 22px. So I thing creating a view with a
    >> height of 50 will fail.
    >>
    >> It's better to use the following:
    >>
    >> [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, [statusBarItem
    >> length], [[statusBarItem statusBar] thickness])]
    >>
    >> This takes the actual length of created StatusItem and the
    >> thickness of the MenuBar into account.
    >>
    >> Hope this helps
    >>
    >> Joachim
  • Unfortunately it does not work for me. I checked with a completely
    new project and my code from below... again I only get kind of local
    coordinates and not screen coordinates :-(
    Do I need any additional includes?

    Fabian
    nexUmoja.org

    On 20.11.2007, at 23:34, Joachim Deelen wrote:

    > As far as I can see the only difference between your and my code is
    > that I'm using a fixed length of the StatusItem instead of the
    > NSVariableStatusItemLength.
    >
    > --
    > Joachim
    >
    > Am 20.11.2007 um 23:03 schrieb [nexUmoja] Fabian Jäger:
    >
    >> Now I use this code:
    >>
    >> // instantiate statusbar-icon
    >> NSStatusBar *systemBar = [NSStatusBar systemStatusBar];
    >> theItem = [systemBar statusItemWithLength:
    >> NSVariableStatusItemLength];
    >> [theItem retain];
    >>
    >> NSView *tmpView = [[NSView alloc] initWithFrame:NSMakeRect(0.0,
    >> 0.0, [theItem length], [[theItem statusBar] thickness])];
    >> [theItem setView:tmpView];
    >>
    >> NSRect globalOrigin = [[[theItem view] window] frame];
    >> NSLog(@"%f/%f", globalOrigin.origin.x, globalOrigin.origin.y);
    >>
    >> [theItem setView:nil];
    >> [tmpView release];
    >>
    >> The output is: "0.000000/0.000000" ... don't really know what's
    >> wrong with the code :-(
    >>
    >> Fabian
    >> nexUmoja.org
  • > The output is: "0.000000/0.000000" ... don't really know what's
    > wrong with the code :-(

    If you're willing to venture into undocumented goodness, you might
    want to have a look at this little category I wrote for a menu bar
    calendar that was supposed to appear right below its NSStatusItem
    years ago:

    //--

    @implementation NSStatusItem (PMForbiddenFruit)

    - (NSWindow*)window {
      if ([self respondsToSelector: @selector(_window)]) {
      return [self performSelector: @selector(_window)];
      }
      return nil;
    }

    - (NSRect)frameInScreenCoordinates {
      NSWindow *theWindow = [self window];
      if (theWindow) {
      return [theWindow frame];
      }
      return NSZeroRect; // you better have a fallback strategy
    }

    @end

    //--

    Peter.
  • Hey,
    your methods are more or less the same what I already tried. And they
    lead to the same result... no screen coordinates. Maybe Apple changed
    something in the NSStatusItem's window?!
    It is really weird, because there are some solutions out there that
    seem to have worked, but do not work for me :-(

    Fabian

    On 22.11.2007, at 09:09, Peter Maurer wrote:

    > If you're willing to venture into undocumented goodness, you might
    > want to have a look at this little category I wrote for a menu bar
    > calendar that was supposed to appear right below its NSStatusItem
    > years ago:
    >
    > //--
    >
    > @implementation NSStatusItem (PMForbiddenFruit)
    >
    > - (NSWindow*)window {
    > if ([self respondsToSelector: @selector(_window)]) {
    > return [self performSelector: @selector(_window)];
    > }
    > return nil;
    > }
    >
    > - (NSRect)frameInScreenCoordinates {
    > NSWindow *theWindow = [self window];
    > if (theWindow) {
    > return [theWindow frame];
    > }
    > return NSZeroRect;    // you better have a fallback strategy
    > }
    >
    > @end
    >
    > //--
    >
    > Peter.
  • For me it's working flawlessly. I can't expose the complete code but I
    did something like the following

    @interface StatusView : NSView {

    NSStatusItem *statusItem;  //!< The Status Area within the Menu-Bar
    }
    - (id)initWithStatusItem:(NSStatusItem*)statusBarItem;

    @end

    @implementation StatusView

    - (id)initWithStatusItem:(NSStatusItem*)statusBarItem
    {
    self = [super initWithFrame:NSMakeRect(0.0, 2.0, [statusBarItem
    length], [[statusBarItem statusBar] thickness])];

    if(self != nil) {
      statusItem = statusBarItem;
      [self setWantsLayer:YES];
      [statusItem setView:self];
    }
    return self;
    }

    @end

    In some other Class the View and the Status Item are created:

    - (void)awakeFromNib
    {
    NSStatusBar *systemStatusBar = [NSStatusBar systemStatusBar];
    statusItem = [systemStatusBar statusItemWithLength:[userDefaults
    integerForKey:kPWPreferenceSize]];
    [statusView initWithStatusItem:statusItem];
    }

    I get the position on screen with the following:

    NSRect rect = [[self.statusView window] frame];

    The position is returned in absolute Screen coordinates. I really
    don't see your problem ;-(

    BTW: I'm using Garbage-Collection so you won't see any retain/release
    or autorelease.

    regards
    Joachim

    Am 22.11.2007 um 09:09 schrieb Peter Maurer:

    >> The output is: "0.000000/0.000000" ... don't really know what's
    >> wrong with the code :-(
    >
    > If you're willing to venture into undocumented goodness, you might
    > want to have a look at this little category I wrote for a menu bar
    > calendar that was supposed to appear right below its NSStatusItem
    > years ago:
    >
    > //--
    >
    > @implementation NSStatusItem (PMForbiddenFruit)
    >
    > - (NSWindow*)window {
    > if ([self respondsToSelector: @selector(_window)]) {
    > return [self performSelector: @selector(_window)];
    > }
    > return nil;
    > }
    >
    > - (NSRect)frameInScreenCoordinates {
    > NSWindow *theWindow = [self window];
    > if (theWindow) {
    > return [theWindow frame];
    > }
    > return NSZeroRect;    // you better have a fallback strategy
    > }
    >
    > @end
    >
    > //--
    >
    > Peter.
  • Hey,
    I tried several solutions on different Macs now and it seems to be a
    problem of Tiger 10.4.11, because on Leopard it works fine without
    any problems, but in Tiger I always get the same (wrong) results ...

    Fabian

    On 23.11.2007, at 23:26, Joachim Deelen wrote:

    > For me it's working flawlessly. I can't expose the complete code
    > but I did something like the following
    >
    > @interface StatusView : NSView {
    >
    > NSStatusItem *statusItem;            //!< The Status Area within the Menu-Bar
    > }
    > - (id)initWithStatusItem:(NSStatusItem*)statusBarItem;
    >
    > @end
    >
    > @implementation StatusView
    >
    > - (id)initWithStatusItem:(NSStatusItem*)statusBarItem
    > {
    > self = [super initWithFrame:NSMakeRect(0.0, 2.0, [statusBarItem
    > length], [[statusBarItem statusBar] thickness])];
    >
    > if(self != nil) {
    > statusItem = statusBarItem;
    > [self setWantsLayer:YES];
    > [statusItem setView:self];
    > }
    > return self;
    > }
    >
    > @end
    >
    > In some other Class the View and the Status Item are created:
    >
    > - (void)awakeFromNib
    > {
    > NSStatusBar *systemStatusBar = [NSStatusBar systemStatusBar];
    > statusItem = [systemStatusBar statusItemWithLength:[userDefaults
    > integerForKey:kPWPreferenceSize]];
    > [statusView initWithStatusItem:statusItem];
    > }
    >
    >
    > I get the position on screen with the following:
    >
    > NSRect rect = [[self.statusView window] frame];
    >
    > The position is returned in absolute Screen coordinates. I really
    > don't see your problem ;-(
    >
    > BTW: I'm using Garbage-Collection so you won't see any retain/
    > release or autorelease.
    >
    > regards
    > Joachim
previous month november 2007 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today