I have created a NSStatusItem and I have assigned two key equivalents within interface builder (Xcode 4.0). These are for the preference menu cmd-, and the quit option cmd-q. Both of these will work when the Menu is highlighted/open but will not work otherwise even if the application is the foremost. Any ideas on why this is happening or how I can change this?
The operating system passes key events that it doesn't handle to the front application, which compares them to any key equivalents in its main menu and current window. They are not compared to items in the status bar, and since the status bar is actually a different application, it won't matter that your application is in the foreground. When you have the menu open, it is the window in focus. This is why it works in those circumstances.
Since the status item is only active while the menu is open, you need to get the key equivalents using one of two other methods. The first, newer method is to use event taps. I have never used this, so I can't advise on how to set it up. The other, older option, is to use hot keys. This method may become unsupported in the future, but if you are interested I posted an example in this answer.
My guess: your NSMenu is not in the responder chain. If you can figure out how to get it in there, you can probably get this to work.
Related
I'm customizing the menus in my Mac Catalyst app. I've added two items, as you can see in the following screen shot ("Set Window Size" and "Open Separate Document Viewer"). But I want to get rid of the default menu items that appear between these two items (the four tab-related functions).
In buildMenuWithBuilder, I can remove some items (child menus) like this:
[builder removeMenuForIdentifier:UIMenuMinimizeAndZoom];
But there is no defined identifier for the child menu containing the tab functions. More significantly, it doesn't yet exist when buildMenuWithBuilder runs. If I put this code at the end of that method...
UIMenu *test = [builder menuForIdentifier:UIMenuWindow];
NSArray *test2 = [test children];
...then test2 contains only two default menus, UIMenuMinimizeAndZoom and UIMenuBringAllToFront, plus my custom menus. So even if I had its identifier, I suspect removing it here would have no effect.
More oddly, it appears between my two custom menus, even though I'm adding those one after the other with insertChildMenu:atStartOfMenuForIdentifier:.
Finally, I noticed that when I open a second scene (in a new Mac window), these tab options disappear from the Window menu and don't come back. It seems that macOS is initially deciding these functions could be relevant to my app, but then when I open a scene, it decides they're not relevant and removes them. So I'm wondering if there is a way to tell macOS from the start not to include these menu items?
I thought this might be related to the NSWindow property tabbingMode, but setting my main window to NSWindowTabbingModeDisallowed makes no difference. My only Mac development experience is through Mac Catalyst, so I don't know what else to try.
I think if you disable tabs completely, they’ll go away. This is a bit of a hack because you need to call AppKit code, but an Apple engineer gave it to me:
Class _nswindow = NSClassFromString(#"NSWindow");
[_nswindow setAllowsAutomaticWindowTabbing:NO];
I am new to the cocoa mac development, Right now i am developing a mac app having several server hit after a particular time. If the hit gets desired data then I need to to show the equivalent window and to show the window i am using [myWindow showWindow:self] method. It shows desired window and set the key window to my visible window is that myWindow.
Each and everything is fine till now but the problem is that suppose when a user start working on any window and open several other child window then unfortunately my show window get called and the focus of my working window transferred to other window.
After several searches i found that i can get the focused window by accessing the [[NSApplication sharedApplication]keyWindow]delegate], I applied several condition that when my this and this window is on key window then don't hit server.
But the problem is not get solved. Now i think setting a keyWindow to my current working window will be best option.
Please suggest me what can i do and how i can forcefully set a window as my key window.
Any Help would be appreciated.
Thanks In advance.
If I understand your question correctly you wish to bring a window forward if it receives input from your server but without moving it in front of the current main or key windows.
The method you are using, showWindow:, belongs to NSWindowController and both shows a window and makes it key.
What you need to look at are the NSWindow methods for managing the window levels, orderFront: et al.
In particular you might want to use orderWindow:relativeTo: which allows to place a window in front/behind another window. For example:
[<window> orderWindow:NSWindowBelow
relativeTo:NSApp.keyWindow.windowNumber];
will move a window to be immediately behind the current key window, and in front of any other windows behind the key window.
HTH
In my current project I am working with a specific implementation of the jface ProjectionViewer attached to a TextEditor nested in a MultiPageEditor.
My task is now to implement a custom reaction to Ctrl-Z, and from what I get this is best done by attaching a specific implementation of IUndoHandler to the Viewer, all of that would be no problem.
But, pressing Ctrl-Z while having that TextEditor focused fails to cause any reaction that would be expected. While clicking "Undo Typing" in the context menu, which displays the associated key combination Ctrl-Z causes the TextViewerUndoManager.DocumentUndoListener's notification method is called, no line of code in the TextViewerUndoManager is touched when pressing Ctrl-Z.
As a possible source of this problem I assumed that maybe a handler might be defined for this key combination in an extension point, since I had previously experimented with this mechanism, but the plugin.xml does not define any key combinations nor undo handlers apart from one that is associated with a special context menu for a different widget.
It might be worth to note that Ctrl-C and Ctrl-V work as intended.
I need to find out what happens when Ctrl-Z is pressed and why nothing is relayed to the TextViewerUndoManager.
It would be very helpful if someone could describe the progress how eclipse handles these key combinations normally and decides which command is appropriate.
Thanks in advance
Cntrl+Z- undo is processed using OperationHistorySupport. Look at UndoActionHandler class.
Binding support is implemented using keydown event filter using WorkbenchKeyboard ( all keydown events first filtered using this class. this is how BindingService was implemented). This will figure out correspond command for the key binding.
DocumentUndoManager.UndoableTextChange is where undo operation is handled.
I am implementing a text service on windows. Things work fine. However when I shift window focus to another application and shift focus back to the original application, the selected text services gets de-activated (I notice a call to ITfTextInputProcessor::Deactivate). I think this call is unexpected. Post this call, The service has to be re-activated manually. I am surely doing something goofy. Just that I don't know what it is.
Offhand, I'd say that you are indeed doing something goofy. :) In particular, I'd pay careful attention to your ITfThreadMgrEventSink::OnSetFocus implementation (and, obviously, you need to implement ITfThreadMgrEventSink in your text service and connect it via AdviseSink if you haven't already.)
After more research, I've figured out what’s happening:
When you set focus back to Word, TSF gets the current thread’s active keyboard layout (actually a locale ID).
It then compares that keyboard layout with the language ID of the currently active text service.
If they’re different, TSF then activates the text service for the active keyboard layout, and deactivates any previously active text service.
I believe this behavior is different on Vista/Windows 7.
The fix would be to use LoadKeyboardLayout/ActivateKeyboardLayout to set the process keyboard layout in your ITfTextInputProcessor::Activate implementation. Apparently some apps also need you to call ITfInputProcessorProfiles::ChangeCurrentLanguage() as well.
I have a document based application. Every document can have multiple windows. Every window is automatically added to the "Window" menu. However, they are added in a more or less random and useless order. I would like the window titles to be organized according to the NSDocument they belong to, similar to how XCode or Photoshop do it.
How can I best do that? How can I prevent the default behaviour of AppKit to add all windows to this special menu, and where should I put the code that adds the menu items in the "correct" manner? I don't want to put handlers into every window controller!
It sure does seem like this is something Cocoa should do automatically. I don't know whether it does, but the first thing to check is whether the window controllers are properly connected to their documents. Does your document subclass's windowControllers property contain all the right objects?
If that's no good, then from NSWindow's reference it looks like the only way to prevent a window whose title has been set from being added to the Windows menu is -[NSWindow setExcludedFromWindowsMenu:]. It looks like you'll want to call that on all your windows, then set up an object (perhaps in the MainMenu nib) that takes care of all the windows' positions and grouping in the Windows menu (via NSApplication's methods). You may need to put in special disabled items and the like to get the grouping to look right. I would hope that windows could still be manually added even if you've previously asked them to be excluded.