Friday, March 15, 2013

Obj-C Way to re-position the window buttons

Obj-C Way to re-position the window buttons easily

Because of the new tabs that are being worked on for Firefox have yet to drop the window buttons down. I decided to take a look myself to see how this could be done for them.

First I examined the InAppStoreWindow custom class available for download. Unfortunately, that class was to complex for our needs and does the drawing itself, when we want to use the native buttons.

Second, I went to examine Chromium's source code. They accomplish this as well, but it was quite complex for simply moving buttons. I figured there had to be a better way. There was.

Through a little digging in APIs and browsing through some API source, I noticed an interesting method you can call to receive an Array of objects. I did some experiementing and discovered the first few objects in this array no matter what.

BUT, thanks to Markus I found another way to do this. With one flaw, that I will cover later.

I can now use:

  //Close Button
  NSButton *closeButton = [_window standardWindowButton:NSWindowCloseButton];
  [closeButton setFrameOrigin:NSMakePoint(closeButton.frame.origin.x, closeButton.frame.origin.y - 10)];

  //Minimize Button
  NSButton *minimizeButton = [_window standardWindowButton:NSWindowMiniaturizeButton];
  [minimizeButton setFrameOrigin:NSMakePoint(minimizeButton.frame.origin.x, minimizeButton.frame.origin.y - 10)];

  //Zoom Button
  NSButton *zoomButton = [_window standardWindowButton:NSWindowZoomButton];
  [zoomButton setFrameOrigin:NSMakePoint(zoomButton.frame.origin.x, zoomButton.frame.origin.y - 10)];

The -10 does the job of moving it down here. There is a problem though, doing this does not allow the cursor hovering to work. But I noticed something. If you resize the window, it will re-align the hover detection area. But in order to do this at launch, just fake a resize at an extremely fast speed. Just use something like:

[_window setFrame:NSMakeRect(_window.frame.origin.x, _window.frame.origin.y, _window.frame.size.width, _window.frame.size.height - 1) display:YES animate:YES];
  [_window setFrame:NSMakeRect(_window.frame.origin.x, _window.frame.origin.y, _window.frame.size.width, _window.frame.size.height + 1) display:YES animate:YES];

This just slightly budges the window, but it is enough to get the job done. Just call this applicationDidFinishLaunching or AwakeFromNib, etc.

Hopefully this helps someone.

1 comment:

  1. An easier way to get the NSView objects for the titlebar buttons is to use e.g. [aWindow standardWindowButton:NSWindowCloseButton]. And you can use setFrameOrigin instead of setFrame to move them.