How to force any application's window to redraw - objective-c

I am looking for a way to force any window (even the ones where I am not the owner) to redraw. It has to work for all window (cocoa, carbon , ...)
Do you have any pointer to achieve this?
Thanks in advance for your help,
Regards,

You must set this property in the initWithWindow method [self setShouldCascadeWindows:NO];
,here the self refers to the window that is being initiated.

Related

Make NSWindow truly the highest level (above mouse, above mission control/expose)

I was wondering if it is possible to make my NSWindow show above absolutely everything. I current set the window level to CGShieldingWindowLevel using the code...
[self setLevel:CGShieldingWindowLevel()];
...and this does a great job for the most part, but it isn't quite enough. The window is not drawn when mission control or expose is active, and it is drawn below the mouse. I was wondering if it was possible to crearte a truly "top level" which would be drawn above all these elements.
Any help would be greatly appreciated. Thanks!
In regards to your question about Expose, you probably just haven't set your collection behavior correctly. Make a subclass of NSWindow, and somewhere in your initialization do something along the following:
self.collectionBehavior = (NSWindowCollectionBehaviorStationary | NSWindowCollectionBehaviorIgnoresCycle);
If you want your window on all spaces (which you probably do) don't forget to also add NSWindowCollectionBehaviorCanJoinAllSpaces.
In terms of your question about the mouse, unfortunately I do not think there's a way to draw above it.

Possible to check if nib is already loaded?

In a loop i am using the following code to load the preferences window if the user has not entered his/her settings.
[NSBundle loadNibNamed:#"prefs" owner:self];
My problem is that everytime the loop runs a new window opens again and again until, is there any way to check if the window or nib is already loaded once?
Thanks! :)
Rather than micro-managing the nib loading as you are doing, just use a subclass of NSWindowController to handle the preferences window. NSWindowController handles all the nib management for you, you just need to call -showWindow: to display the window. The only real trick with NSWindowController is to make sure you hook up the window outlet of File's Owner in the nib itself.
To instantiate the class, use ‑initWithWindowNibName: passing in the name of the nib.
As Ief2 mentioned, you should configure this object to act as a singleton.
Maybe you can make a class named PreferencesController, make that class load the nib when requested, save the the window in an ivar. Every time you create an instance of the class and activate it, check if the window ivar is nil. If it is, load the nib, otherwise just make the window key and order front.
In addition to storing the window, you could also monitor it for when the user closes it. When he or she does, you can release your ivar and ser it to nil. Now when you request it again, you'll see you have no window cached and you'll have to reload the nib. It saves memory though.
It also may be advised to make a shared instance of the class. I cannot include a sample because I'm on my iPod touch, but a quick Google search should be really helpful.
Hope it helps,
ief2
EDIT: The link below holds an example about singletons:
http://eschatologist.net/blog/?p=178

Using NSProgressIndicator inside an NSMenuItem

I'm trying to use a NSProgressIndicator (indeterminate) inside of a statusbar-menu. I'm using an NSView-object as view for the menuitem, and then subviews the progress indicator to display it. But whenever i try to call the startAnimation: for the progress, nothing happens. When i try do the very same thing on a normal NSWindow it works perfectly, just not when inside a menuitem.
I'm new to both cocoa and objective-c so I might've overlooked something "obvious" but I've searched quite a bit for a workaround but without success. I found something about menuitems cant be updated while shown and that you need to use a bordeless window instead. But I have not been able to confirm this in any documentation.
Edit:
Ok, almost works now. When using the setUsesThreadedAnimation: and from a MenuDelegate's menuWillOpen and creating a new thread. This thread runs a local method:
-(void) doWork(NSProgressIndicator*) p{
[p startAnimation:self];
}
This will start the progressindicator on a random(?) basis when opening the menu. If I call startAnimation: directly without going through doWork: (still using a new thread), it never works. Doesn't setUsesThreadedAnimation: make the progress-bar create it's own thread for the animation?
Solved it by using:
[progressIndicator performSelector:#selector(startAnimation:)
withObject:self
afterDelay:0.0
inModes:[NSArray
arrayWithObject:NSEventTrackingRunLoopMode]];
Inside the menuWillOpen:, the problem seems to have been calling startAnimation: before the progressbar was finished drawing itself.
How are you referencing the NSProgressIndicator that is in the view (and the one in the window, for that matter)? For example, do you have a controller class that has IBOutlet's hooked up to the progress indicators? If you are using an IBOutlet, are you sure it's hooked up properly in the nib file?
Also, where and when are you calling startAnimation:? (We need to see some code).
One thing that can sometimes happen is that you forget to hook up an IBOutlet in the nib. Then, when you attempt to tell the object to do something in code at runtime, the IBOutlet is nil, and so what you think is a message being sent to your object is in fact, a message being sent to nil. In other words, it's just ignored, and effectively looks like it's not working.
Provided you do have a (potentially) valid reference to the UI object, the other common issue you'll see is when a developer is trying to send a message to the object at "too early" of a time. In general, init methods are too early in the controller object's lifetime to be able to send messages to user interface objects—those IBOutlet's are still nil. By the time -awakeFromNib is called, IBOutlet's should be valid (provided you hooked them up in IB) and you can then send the message to the UI object.
Have you told it to use threaded animation via -setUsesThreadedAnimation:?

Cannot set an NSWindow's position

I have a class that extends NSWindowController and I am trying to position the window it controls. The window displays all of the expected contents and functions correctly, but when I try and position its starting location on the screen in the initWithWindowNibName method, the position does not change. Here is the code:
NSPoint p = NSMakePoint(100, 50);
[[self window] setFrameTopLeftPoint:p];
This seems very straight forward and I'm not sure what the problem is.
Thanks for any ideas.
(Found the problem. I did not have the window wired up to the Class in IB.)
Wevah has the right idea, though I'll try to expand on it a bit.
If you were to try adding this line to your initWithWindowNibName: method:
NSLog(#"window == %#", [self window]);
You would likely see the following output to console:
window == (null)
In other words, the window is still nil, as init* methods are so early on in an object's lifetime that many IBOutlets or user interface items aren't quite "hooked up" yet.
Sending a message to nil is perfectly fine: it's simply ignored. So, basically your attempt to position the window has no effect because it basically equates to [nil doSomething];
The key then is to perform the positioning of the window later on in the controller object's lifetime, where the IBOutlets and other user interface objects are properly hooked up. As Wevah alluded to, one such method where things are properly hooked up is
- (void)awakeFromNib;
or in the case of NSWindowController, the following one as well:
- (void)windowDidLoad;
Hope this helps...
Try putting that code in awakeFromNib.

How to be notified of the Minimize button being pressed in an OSX Window?

N.B.: this relates to private (SPI) functions of the CoreGraphicServices framework.
I am currently running a CGSConnection to the Windowserver as the UniversalController (with the Dock killed), and would like to know how I can be notified that a CGSWindow has had the yellow minimize blob clicked.
Is there a notification event that I can watch for with CGSRegisterConnectionNotifyProc?
Perhaps the answer lies in HIToolbox? Any experienced CGS hackers out there have an idea?
Thank you.
CGSGetWindowEventMask or CGSGetWindowGeometry is my best guess but I've never tried my hand at it
NSWindow has this method:
- (BOOL)windowShouldZoom:(NSWindow *) toFrame:(NSRect)proposedFrame
method that you can implement.
Or maybe i don't understand your question...