I need to maximize compatibility for a program that I want it to works from 10.6 to Big Sur. That's why I use XCode 3.2.2.
It seems to work on Big Sur but the function [nswind displayIfNeeded];
it doesn't do anything.
displayIfNeeded instance method still available I see on apple.com but do nothing.
I need this function to redraw portions of the window that become dirty by use.
Before displayIfNeeded I invalidate rect with: setNeedsDisplayInRect
Minimal code:
# window init
NSWindow *NSWind=[super initWithContentRect:NSMakeRect(0, 0, g_winw, g_winh) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:NO];
NSView *GPview = [[GRAPH alloc]initWithFrame: NSMakeRect(0, 0, s_winw, s_winh-g_menuh)];
[GPview setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
[[self contentView] addSubview:GPview];
# User action
[GPview setNeedsDisplayInRect: NSMakeRect(r->left,g_winh-(r->bottom-r->top)-r->top,r->right-r->left,r->bottom-r->top)];
[NSWind displayIfNeeded];
Related
I have written a sample code in objective-c to draw two windows and making the first window the parent of 2nd window, so that when first window is moved, second window also moves. I can see two windows are drawn, but the child window is not moving when I move the parent window. What is wrong with this code?
NSRect frame = NSMakeRect(0, 0, 200, 200);
NSUInteger styleMask = NSTitledWindowMask;
NSRect rect = [NSWindow contentRectForFrameRect:frame styleMask:styleMask];
NSWindow * window = [[NSWindow alloc] initWithContentRect:rect styleMask:styleMask backing: NSBackingStoreBuffered defer:false];
[window setBackgroundColor:[NSColor blueColor]];
[window makeKeyAndOrderFront:NSApp];
NSRect frame1 = NSMakeRect(0, 0, 100, 100);
NSUInteger styleMask1 = NSTitledWindowMask;
NSRect rect1 = [NSWindow contentRectForFrameRect:frame1 styleMask:styleMask1];
NSWindow * window1 = [[NSWindow alloc] initWithContentRect:rect1 styleMask:styleMask1 backing: NSBackingStoreBuffered defer:false];
[window1 setBackgroundColor:[NSColor greenColor]];
[window1 makeKeyAndOrderFront:NSApp];
CFRunLoopRun();
[window1 setParentWindow:window];
Issue 1:
setParentWindow isn't executed. CFRunLoopRun:
Runs the current thread’s CFRunLoop object in its default mode indefinitely.
Set the parent window before CFRunLoopRun.
Issue 2:
From the documentation of parentWindow:
This property should be set from a subclass when it is overridden by a subclass’s implementation. It should not be set otherwise.
Use addChildWindow:ordered: instead.
[window addChildWindow:window1 ordered:NSWindowAbove];
As already stated the parent <-> child relationship must be present in order to let the child windows "follow" the parent.
In my case the problem was that the window was create, hidden with orderOut and then shown again. You should never call orderOut on a child window because as stated in the official doc:
Calling orderOut: on a child window causes the window to be removed
from its parent window before being removed.
So when the window is shown again the parent <-> child relationship is no more present and the child window is not moved when the parent moves.
Also note that invoking setIsVisible and passing it FALSE will internally trigger a call to orderOut.
So if you just want to hide the window without loosing the relationship with the parent you can call
[window setAlphaValue:0];
[window setViewsNeedDisplay:TRUE];
I'm writing some glue GUI code for a scripting language implementation, and need to be able to programmatically create windows and intercept the key and mouse commands on their views. I've subclassed both NSWindow and NSView.
When I open a window for the first time, I get a window with a title bar and controls. If I close this window and open another, the controls and title don't appear in the new window. However, if I click where the controls should be, the new window (with invisible controls) still closes.
Is there something I'm doing in my window initialization that could cause this?
+ (HMSLWindow*)hmslWindowWithTitle:(NSString *)title frame:(NSRect)frame {
HMSLWindow* hmslWindow = [[HMSLWindow alloc]
initWithContentRect: frame
styleMask: NSMiniaturizableWindowMask | NSTitledWindowMask | NSClosableWindowMask
backing: NSBackingStoreBuffered
defer: YES];
hmslWindow.title = [title retain];
[hmslWindow setContentView:[[HMSLView alloc] initWithFrame:frame]];
hmslWindow.delegate = [[HMSLWindowDelegate alloc] init];
[hmslWindow cascadeTopLeftFromPoint:NSZeroPoint];
[hmslWindow makeKeyAndOrderFront:self];
[[HMSLWindow windowDictionary] setObject:hmslWindow forKey:[NSNumber numberWithInteger:hmslWindow.windowNumber]];
return hmslWindow;
}
- (void)close {
[[HMSLWindow windowDictionary]
removeObjectForKey:[NSNumber numberWithInteger:self.windowNumber]];
[self.contentView autorelease];
[self.delegate autorelease];
[self.title autorelease];
[super close];
}
First window:
Second window (contentView with white background is correct, but the titlebar is now empty):
I'm having this problem on OSX Lion when entering/exiting fullscreen. I tried to reapply the style mask without success:
NSUInteger styleMask = NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask;
styleMask |= NSTexturedBackgroundWindowMask;
window = [[NSWindow alloc] initWithContentRect:windowFrame
styleMask: styleMask
backing:NSBackingStoreBuffered
defer:NO];
and the fullscreen notification
(void)didExitFull:(NSNotification *)notification {
NSUInteger styleMask=[window styleMask];
[window setStyleMask:styleMask|NSMiniaturizableWindowMask];
}
It seems that the miniaturize button is not getting enable again.
I also found this UI Usability problems on MacOSX 10.6 here
Please override the following function
- (NSApplicationPresentationOptions) window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions
{
return (proposedOptions| NSApplicationPresentationAutoHideToolbar);
}
And do not set styleMask after exitFullscreen. Let the system do it.
I would like to create a full screen application (mac) but eventhough I have the window fullscreen;
[window setFrame:[window frameRectForContentRect:[[window screen] frame]]display:YES animate:YES];
I can't get rid of the title bar? Can you change the above code to make the window without a titlebar or do you have to do it completely different? Thanks :)
CocoaWithLove has a good article about it:
http://cocoawithlove.com/2009/08/animating-window-to-fullscreen-on-mac.html
fullscreenWindow = [[FullscreenWindow alloc]
initWithContentRect:[mainWindow contentRectForFrameRect:[mainWindow frame]]
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:YES
screen:[mainWindow screen]];
[fullscreenWindow setLevel:NSFloatingWindowLevel];
[fullscreenWindow setContentView:[mainWindow contentView]];
[fullscreenWindow setTitle:[mainWindow title]];
[fullscreenWindow makeKeyAndOrderFront:nil];
I successfully placed the window over the titlebar using the window level NSScreenSaverWindowLevel, instead of NSFloatingWindowLevel suggested in Macmade's answer.
fullscreenWindow = [[NSWindow alloc]
initWithContentRect:[[NSScreen mainScreen] frame]
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:YES];
[fullscreenWindow setLevel:NSScreenSaverWindowLevel];
// Perform further configuration here, e.g. setTitle, setBackgroundColor etc.
[fullscreenWindow makeKeyAndOrderFront:nil];
I have this code set to run on my app launch:
NSRect rect = NSMakeRect(0, 0, 200, 50); //The location of the window
NSWindow *win = [[NSWindow alloc] initWithContentRect:rect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
[win setOpaque:NO];
[win setLevel:NSFloatingWindowLevel];
//[win setBackgroundColor:[NSColor clearColor]];
//or
NSView *myView = [[NSView alloc] initWithFrame: NSMakeRect(0, 0, 200, 50)];
NSButton *myButton = [[NSButton alloc] initWithFrame:NSMakeRect(10, 5, 180, 40)];
[myView addSubview: myButton];
[win setHidesOnDeactivate:NO];
[win setContentView: myView];
[win orderFront: nil];
It works as expected (displays a button in the bottom left hand corner of the screen) for about a second, then it disappears. Why is it disappearing? Memory management, or something else, and how do I fix it?
First, it is extremely odd to be building user interface without simply using Interface Builder. Can be done and there are a handful of reasons to do so, but they are pretty few and far between.
Next, that code, by itself, isn't enough to say what has gone wrong. Creating a UI programmatically begs a whole series of questions; gc or not? ... how is your run loop configured? ... do you have a properly configured app wrapper?
As Abizem said, the most obvious guess would be that you have GC enabled and you haven't rooted the window in some global variable somewhere, directly or indirectly. It "just works" in a standard Cocoa application because NSWindow instances are rooted via the Cocoa application infrastructure (the Windows menu, specifically).
Are you working with Garbage Collection?
Do you have an iVar that is holding on to win? It could be that it is being garbage collected out from under you.