NSWindow resize indicator not visible - macos

How do I show resize indicators for an NSWindow without Titlebar?
I created a new Xcode project(for Mac app) with storyboard. I just disabled the checkbox Title Bar in Appearance(It hides the Title bar of NSwindow).
The strange thing was, after disabling the TitleBar, NSWindow was not showing resize indicators while mouse was above the window edges. Although if I drag at edges it was resizing.
I guess this is a bug, because if the window can be resized by dragging the mouse over edges, it must show the resize indicators.
As it can be seen in the image, the resize indicators are seen after user drags the window, but many users would think that since there is no resize indicator, the window is not resizable.

I've fixed this issue by subclassing NSWindow and overriding canBecomeKeyWindow to return YES:
#import "MyWindow.h"
#implementation MyWindow
- (BOOL)canBecomeKeyWindow {
return YES;
}
#end
Not updating resize cursors in this case looks like Apple bug. Documentation states "The value of canBecomeKeyWindow property is YES if the window has a title bar or a resize bar, or NO otherwise.", so I expect that canBecomeKeyWindow will return YES for resizable window. But it doesn't.
UPD: Checked on 10.10.5. Hopefully, you will have same behaviour on 10.11.

I have not checked this, but you could set the resize indicators manually. I think I would add four NSTrackingAreas to the windows contentView subclass (one for each side of the window, only few pixels in height/width).
In the mouseEntered() method, create a new NSCursor object for the appropriate mouse position. Remember that the position could change, so use the mouseMoved() method as well.
On mouseExited() reset the cursor.
Again, I have not tried this, but it should work.
PS: Don't forget to file a radar on this ;)

Related

How to animate closing NSWindow to NSStatusItem?

When you minimize an NSWindow you get a nice animation to the Dock. How to achieve a similar animation for "minimizing" to an NSStatusItem in the menu bar?
I have it set up where the NSStatusItem appears when you close the NSWindow but there is no animation.
I've tried animating the window frame but due to various layout contraints it has a minimum size that gets in the way.
To animate the whole NSWindow is not the right way and will result in a rubbish looking animation. I would suggest to capture a snapshot of the window and adding it to a transparent full screen window to animate layer of the image view. This way its fare more smooth. To get an idea how it could be implemented please take a look at this project on git.
Hope this will help.

NSScroller inside a NSScrollView does not change position when resizing the window (in Swift)

I have created a NSView with Interface Builder (Xcode 6.1). The NSView has constraints for each direction. When changing the window-size with the mouse manually, the NSView is getting a new size and the NSScroller gets a new position at the correct right border of the window, as expected.
When I set the window size manually (before it is made visible) with
myTextView.enclosingScrollView!.window!.setFrame(theRect)
or with
myTextView.window!.setFrame(theRect)
Then the window resizes well (as soon as it becomes visible), the NSTextView resizes also but the NSScroller (which is automatically part of the NSTextview and has not been created or modified seperately) does not move but stands in the middle of the ScrollView at its old position. The Text entered in the NSScrollView uses the full size and floats behind the NSScroller, which seams to stand in top of the text.
In the case, the Window is visible before setting the Window Size, then the scroll-view is truncated at the right side or bottom side.
When I change the window manually, after settzing the size and getting this behaviour, the NSScroller jumps to it's right position and the NSTextView is not longer truncated. So changing the Window Size manually does something more that I do programmatically.
What must I do, that the Scroller moves with the NSView, like changing the Size of the Window with the Mouse?
This is a typically problem when calling UI-functions from a background thread.
It can besolved, when calling from main-thread or forcing to called by the main-thread with this command:
dispatch_async(dispatch_get_main_queue())
{
// Place the UI Functions here
}
Please have a look at: Open File Dialog crashes in Swift

Change NSView background color when window has focus

I have noticed when an apps window contains an Outline view (such as XCode) it changes color when that window is in focus. With XCode for example, if the window is current then the outline view has a blueish background, if it looses focus it goes grey,
Can anyone help me to replicate this? I presume its something to do with drawRect: but can only manage to get the color to change when the window loads.
Maybe its a built in function and I'm just missing something?
All you have to do in your -drawRect: is check whether the window has main status and draw accordingly:
- (void)drawRect:(NSRect)rect
{
if ([[self window] isMainWindow]) {
// draw active appearance
} else {
// draw inactive appearance
}
}
A window's delegate gets messages whenever a window gets or resigns main or key window status. You can implement the appropriate methods (like -windowDidBecomeMain: and -windowDidResignMain:) in your window delegate to update the window and its subviews as necessary.

How to change the height of an NSWindow titlebar?

I want to change the height of an NSWindow titlebar.
Here are some examples:
And…
I could use an NSToolbar, but the problem is that I can't place views very height (For example: I can't place the segmentedControl higher than in the picture because there is still the titlebar)
If I remove the titlebar I can't place a NSToolbar and the window isn't movable.
Have you any ideas?
This is much easier than one would think. I too went on a quest to do something similar for my app.
Real App Store app:
My App Store app look-alike:
No disrespect to INAppStoreWindow, it is a very good implementation and solid. The only draw back I saw from it though was that there was a lot of drawing code along with hardcoded settings for the TitleBar colors which Apple can adjust at anytime.
So here is how I did it:
A) Create a standard window with a Title Bar, Close, Minimize, Shadow, Resize, Full Screen - Primary Window all set.
Note: You do not need a textured window nor should you set a title
B) Next add a standard toolbar with these settings:
Icon Only
Visible at Launch - ON
Customizable - OFF
Separator - ON
Size - Regular
Remove all the Toolbar Items and add only these in the following order
NSSegmentControl (51 x 24) -- | Flexible Space | -- NSSearchField (150 x 25)
C) In your content View directly under the toolbar add a regular sized NSButton set like so:
Bordered - OFF
Transparent - OFF
Title -
Image -
Position - Text below the button
Font - System Small 11
Ok, pretty easy so far, right?!
In your Window Controller or app delegate....
setup IBOutlet(s) to your NSButton(s)
Note: Remember to hook up your IBOutlet in interface builder
Ok don't be scared we have to write a tiny bit of code now:
In awakeFromNib or windowDidLoad....
Get the content views' superview (aka NSThemeView)
Remove your button from its superView
Set the frame of your button
Add the button back to the theme view
So the code would look similar to this:
NSView *themeView = [self.contentView superview];
NSUInteger adj = 6;
[self.btnFeatured removeFromSuperview];
self.btnFeatured.frame = NSMakeRect( self.btnFeatured.frame.origin.x,
self.window.frame.size.height - self.btnFeatured.frame.size.height - adj,
self.btnFeatured.frame.size.width, self.btnFeatured.frame.size.height);
[themeView addSubview:self.btnFeatured];
That's it! You can use your outlet to enable/disable your button, setup a mask image when selected, enable/disable the toolbar or even hide everything and add a window title. All of this without worry if Apple changes their standard Window Titlebars.
P.S. No private frameworks were used in this posting whatsoever!
INAppStoreWindow is a NSWindow subclass, it tell you how to change the height of title bar.
https://github.com/indragiek/INAppStoreWindow
http://iloveco.de/adding-a-titlebar-accessory-view-to-a-window/
This example tells you how to add buttons in the title bar.
You'd have to subclass NSWindow and do a custom window frame drawing. It's not only about a titlebar. It's about whole window frame (so you can, actually, put close/minimize/zoom buttons at the bottom if you wish).
A good starter is at "Cocoa with love" website.
There are a few new solutions based on INAppStoreWindow and without warning and log message, for anyone who wants to change the height of NStitlebar, change the position of traffic light, add an item(e.g. a NSbutton) on NStitlebar and change its position, please check below.
WAYWindow:
https://github.com/weAreYeah/WAYWindow
NStitlebar_with_item:
https://github.com/ZHANGneuro/NStitlebar_with_item

Change color of title bar in cocoa

This must have been asked before, but after Googling I still can't find the answer.
How do you change the color of the title bar (The bar that you can click and drag around with the close, minimize and maximize buttons) to a different color than the default gray in Cocoa?
If you set the background color of a "textured" window (a distinction that isn't really all that visible in Snow Leopard) that color will be applied to the titlebar as well. This is what Firefox does.
I would recommend though not having a real titlebar (i.e. setting your window to have no titlebar) and using +[NSWindow standardWindowButton:forStyleMask:] and putting your own buttons in the "titlebar". This allows you more control and is way way less hacky.
If it's a panel, you can change it to black by instantiating it as a HUD window.
Otherwise, you can't. Ever notice how there aren't any Aqua windows with different-colored title bars roaming around in other apps? This is why.
The only other way to change the appearance of the title bar (without relying on private implementation details such as the existence of a frame view) is to make the window borderless and create its title bar and window buttons from the ground up.
If you go with Colin's approach of making the window textured in interface builder (check box in the attributes of the window), here's the line to change the background color of the window you'd put in this function of the appDelegate.m file
//In this function --->
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
//type this
[_window setBackgroundColor: NSColor.whiteColor];
If you don't mind private API, you could subclass NSThemeFrame.
Setting title bar appears as transparent
self.window.titlebarAppearsTransparent = YES;
And setting window background color as you wish

Resources