Cocoa documnt based app does not do anything on Command W - objective-c

I would like it to close on Command ⌘-W as per the standard. There is a close button on window and it's enabled so I'm not sure what is eating the close command keyboard shortcut.
The content view is a webview if that makes any difference.
I've implemented windowWillClose and windowShouldClose but none of them are hit during debugging when pressing Command ⌘-W.

Does the File menu at the top of the screen flash when you press Command ⌘-W? That might indicate whether something is eating the key event before it goes to the normal responder chain. For example, I believe it is possible for some javascript in your webview could be eating the event.
Normally the Command ⌘-W is sent to the firstResponder (usually the control where keyboard focus is) and then along the responder chain. This document might be helpful: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html%23//apple_ref/doc/uid/10000060i-CH3-SW10
Some things to try:
Make a text field outside your webview and see if Command ⌘-W works when that text field has focus. That might implicate the webview.
Turn on NSObjCMessageLoggingEnabled.
This produces lots of output, but can show you exactly what methods are called after you press Command ⌘-W.

Related

NSPanel in "Non-Activating"-Mode does not always show correct cursors

I've created a simple Cocoa-Application in XCode 4.6 with an NSPanel instead of the default NSWindow. When I enable the Non-Activating
option and start the application everything works fine:
The panel is displayed in front of everything else and when
the mouse cursor hovers over the panel's edges it changes from a normal
arrow-cursor to the appropriate resize-cursor, so the user knows that he can resize
the panel.
This works fine as longs as I don't click on any other application
as for example Safari or Finder.
From the moment I once give focus to another application,
I can click on and hover over my panel as much as I want, the
cursor style will not change anymore - it always stays an arrow and it's not possible to return to the normal behavior.
The panel stays selectable and in the front, you still can move and resize it,
but the mouse cursor stays an arrow all the time. You then cannot even change it
manually using something like: [[NSCursor crosshairCursor] set].
So I need to find a way to create a NSPanel that keeps the normal
automatic-change-cursorstyle-when-hovering-over-panel-edges-behaviour
even when you give focus to another application.
I have already tried to use an customized NSPanel-class,
where I have overwritten the canBecomeKeyWindow and
canBecomeMainWindow methods, so that they return YES
but even when I make my Panel KeyWindow and MainWindow...
[myPanel makeKeyAndOrderFront:self];
[myPanel makeMainWindow];
...it doesn't solve the cursor issue.
Would be great if someone could help me here :)
PS.: the Base SDK and the Deployment Target are set to 10.8 in my project
So I found out that the described issue has nothing to to with the panel's window-state. It really doesn't matter if it is set to key or to main, instead the cursor-problem (stays arrow all the time)is related to the application's activation state.
Everything works fine as long as the application that owns the panel is active but if you click on another application my application is deactivated and does not get activated again - even if you click on the panel - because the "non-activating"-option is enabled.
The problem is that i need the "non activating"-option because I am creating a status-bar-screen-capturing app that should be displayed and operate in front of everything else but without deactivating any running application. I could solve the cursor problem by
[NSApp activateIgnoringOtherApps];
but then taking a screenshot of a fullscreen video running in Safari would deactivate Safari and minimize the video, which I don't want.
I don’t think it’s possible through normal APIs to change the cursor when your app isn’t active. I’m pretty sure the window system doesn’t allow it: it’d be a violation of the boundaries between apps—if you try to set a cursor from the background, and the foreground app also tries to set a cursor, who would win?
Of course the system can do it (like when you take a screenshot with ⌘⇧4), because that’s in the window system itself.

Cocoa/ObjC: Place a floating window above a modal window

I have two NSWindows. Window A with level 0, and Window B with level 1. I'm using B as a floating window.
This works as expected until I put A as a modal window (i.e., send runModalForWindow:A message to NSApplication). Then B is always behind A.
Is there a way that I can have B above A, even when A is running as a modal window?
Much appreciated for the help.
To put your floating window in front, use [myfloater setLevel: NSModalPanelWindowLevel+1].
Other people are telling you that you will have trouble interacting with the floater, but I've done it and it worked for me. (My floater uses NSPanel of "Utility Panel" style rather than plain NSWindow, but I'm not sure if that's important. You may also need to say [myPanel setWorksWhenModal: YES].)
AFAIK that is not possible.
From the Apple class reference:
NSApplication runModalForWindow:
This method runs a modal event loop for the specified window
synchronously. It displays the specified window, makes it key, starts
the run loop, and processes events for that window. (You do not need
to show the window yourself.) While the application is in that loop,
it does not respond to any other events (including mouse, keyboard, or
window-close events) unless they are associated with the window. It
also does not perform any tasks (such as firing timers) that are not
associated with the modal run loop. In other words, this method
consumes only enough CPU time to process events and dispatch them to
the action methods associated with the modal window.
Given this, your Window A will become the key window and will always be shown on top of any other window of your app. I think this is how modal windows are supposed to work.
As an alternative you can consider using an NSPopover which has a clear presence to the user but does not force your application into a modal state.
Check out this page from the Apple docs on guidelines re various options available to you.
I think if you set the window level to NSScreenSaverWindowLevel, it will always be on top.
You can use orderFront:, orderFrontRegardless, or orderFront:relativeTo:, to have B moved in front of A. However not sure how many tasks can you do in B, as due to the fact that A is modal, you won't be able to interact with B.

Controlling NSSegmentedControl with the keyboard

I have a form in my Cocoa app that contains an NSSegmentedControl that I want to be controllable via the keyboard. It seems that NSSegmentedControl is very reluctant to become the first responder, however.
Setting the initial first responder of the window to the segmented control does nothing -- it will not have keyboard focus when the window is first loaded. It does receive focus if I manually set the first responder like this, however:
[segmentedControl.window makeFirstResponder: segmentedControl];
That will work fine if the only part of the form is the segmented control. If I add another field (say, an NSTextField), and I set the nextResponder of the segmented control to that field, the segmented control will never become first responder. Focus will immediately go to the text field, and pressing tab to switch back to the segmented control doesn't work.
I've tried subclassing NSSegmentedControl and overriding acceptsFirstResponder, becomeFirstResponder, etc. to no avail. The only one that makes any difference is resignFirstResponder -- if I return NO from that method then the segmented control will indeed retain focus, but obviously I don't want it to retain focus all the time.
Any ideas on how to get the control to behave like a normal responder?
It's behaving as intended. Not all controls participate in the "key view loop". Full keyboard navigation is turned on through Universal Access in System Preferences for all apps and it's not for individual apps to implement on their own.
It's best not to use a segmented control in a form intended for heavy keyboard entry. NSPopUpButton works more closely to what we all exepect in a web form so it's not as if it's necessarily the wrong choice in your app's UI.
Rather than answer exactly the question you asked (which someone else can do), I humbly suggest you choose on the side of functionality at the cost of a slightly prettier UI element since that prettier UI element wasn't intended to get along with the keyboard.

ios custom keyboard

Is it possible to change what each key does? I have a client application and the way it needs to work is that each key press is a command to send over the network. I do not need my keyboard to produce letters (the server will do this) when pressed but commands to the server. Currently I have this working by making a custom view that looks like a keyboard however it would look better if it was the ios default keyboard.
Of course I dont expect the code but I need a starting point. My current google searching hasnt gone to good. Maybe a link to an example or some documentation on how to do it.
notes: you will see the first answer below makes a good suggestion but it brings up another point. my keyboard needs to mask the keyboard of the server, so no .com button or any other out of the ordinary keys, so I would also need to edit the layout I guess.
Create a text field with a custom delegate, hide it and set it as the first responder. Then you can hook into the delegate methods to work out what was pressed.

Keeping window of another application active while still receiving mouse events from another app's window?

Is there a way to have my app's window receive keyboard and/or mouse events (i.e. user clicking on window's buttons) while still retaining focus to another, unrelated app?
I've tried configuring my window at different levels, including [myWindow setLevel:NSPopUpMenuWindowLevel] to no avail.
You should be able to handle mouse clicks without ordering your window front by making your views (at least the ones that handle mouse clicks) respond to acceptsFirstMouse: messages by sending NSApp a preventWindowOrdering message and then returning YES.
You should not make your app handle typing without ordering itself front. The user might not realize where their typing is going if the field where it's appearing is obscured by another window.
Found it. Simple, yet elusive.
Use NSPanel and make sure panel style is Non Activating (NSNonactivatingPanelMask) or tick the same option in IB's inspector.