Strange behaviour of NSShadow for customized NSWindow - macos

I subclass the NSWindow and use [self setHasShadow:YES] to set the shadow for window. But the shadow shows abnormally when:
Move the window a little out of the screen, then resize the window to a larger size, then when I drag back the whole window from outside the screen, I find that system does not draw shadow for those part covered by screen before.
the right part without shadow was covered by screen before
To get full shadow, I must resize the window again to let system redraw the shadow.
So is there a way to avoid this behaviour? Maybe it is more efficient to only the shadow for those parts in screen, but I hope it can redraw automatically when the whole window is in screen.

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

Adding an NSView at top left and filling window

I am programmatically adding an NSView to an NSWindow. I want to have the new view appear at the top left and fill the entire window.
I have been messing around with autolayout and manually setting frames and autoresizing masks (not at the same time, obviously), but I'm getting nowhere. Either the view doesn't resize at all, or it resizes proportionally (using autoresizing masks) but it won't fill the entire space. I must be missing something basic.
I am new to Mac Cocoa, although I'm quite experienced at iOS Cocoa Touch. On iOS, CGPoint 0,0 is top left. I assume on Mac from what I'm seeing that it's bottom left. How do you figure out what top left is?
Using the autoresizing mask like below should do the trick:
view.autoresizingMask = NSViewHeightSizable|NSViewWidthSizable
Absence of other resizing masks makes the margins inflexible. So whatever is the current margin (which is zero on all sides, when you add it to the window - Assuming the view occupies the full window frame when being added) is retained.
And top left would be the window's content view's height.
[[self.window.contentView frame].size.height]
I guess you already knew that. :)

Draw NSWindow on one screen only

Let's say we have two screen scenario and a NSWindow,
positioned at the edge of screen 1.
A part of that of that window is also shown on screen 2.
What I would like to achieve, is to draw the window only on screen 1 and to not show the rest on screen 2.
The reason for that is that's some kind of a specially behaving mini window, not a usual one.
Is it possible to assign a certain NSScreen to draw the window on, only?
Two very different approaches:
Use Mavericks: What you looking for sounds like the behaviour of Mavericks' "screens have separate spaces" mode. In this mode a window is never drawn on two screens except during drag operations, at other times the window is draw on one screen with any areas protruding onto adjacent screens clipped. So if you can restrict use to 10.9 this may save you some work.
Borderless Windows: You can create a borderless non-opaque NSWindow, just set the appropriate flags. This is how applications create non-square windows, the visible area of the window is now entirely up to you. Now just clip your drawing to the area on one screen using the standard clipping support. You won't have a standard title bar or controls, unless you emulate them yourself, so you have to implement drag yourself etc. You say you have "some kind of a specially behaving mini window, not a usual one" so that may not be an issue.
Not that I've heard of.
What you could do though is restricting the position of the window e.g. via a NSWindowDelegate and windowDidMove: to listen to position changes and reposition the window appropriately.

Why does this textured NSWindow suddenly change its background gradient when resizing?

Can someone please tell me, why the background gradient of the textured NSWindow in this app suddenly changes, when you make the window a little bit smaller?
This is the minimal example I could find, that exhibits this behaviour. App & Source are available via Dropbox.
-- Updates:
If you put the slider lower,the gradient does not change when resizing the window:
Also, the change seems to happen when the distance between the slider and the window's right border gets smaller than the HIG says it should be.
It is really interesting question =)
I don't shure, but guess, this problem is connected to layers displaying.
If you still want to use textured window, you can put additional NSView object in the interface builder between NSView and NSSlider (NSWindow -> NSView -> NSView -> NSSlider). It fixes the bug.

Resources