I have created a JavaFX application which uses the native menu bar on the Mac via
menuBar.setUseSystemMenuBar(true);
This results in 4 standard Mac menu items in addition to the ones I have defined. My problem is that these additional items are all in english and not in german as the rest of the application. My Mac is set up for german and the Java default locale is german as well. Can anybody tell me how I can modify these default entries so that they obey the language settings of my machine?
I don't know if it is possible to set the language of the menu bar directly using Java code. But you can bundle your application and then add localization folders for every language you want to support.
For example, if your application bundle is called "test.app", simply create a folder test.app/Contents/Resources/German.lproj. Now when you start the application, the standard menu will automatically appear in german language.
You can use NSMenuFX to access the auto generate menu bar on OS X and then rename the menu items like this:
NSMenuBarAdapter adapter = new NSMenuBarAdapter();
// Get the default menu bar as JavaFX object
MenuBar menuBar = adapter.getMenuBar();
// Change the name of the first menu item
menuBar.getMenus().get(0).setText("Hello World");
// Update the menu bar
adapter.setMenuBar(menuBar);
It might not be the most elegant way to do localisation, but for me it works ;)
Related
I want to add custom actions to every window's title bar context menu. The goal is to add an option like in the task view where you can move a window to a different virtual desktop. I was able to do this with hotkeys using GlobalHotKey and WindowsDesktop packages in C#. But I want to do it in the UI as well similar to some Linux desktop environments.
I know you cannot normally do this with the registry like you can with other context menus. When creating your own application I know you can use GetSystemMenu, AppendMenu, etc. and override WndProc to handle it. But this obviously will not work for what I am intending.
The application Moo0 Window Menu Plus achieves the desired effect but I have no idea how they do it.
I have a feeling the solution is probably somewhat hacky but I would still like to know how it could be done. I am open to using any language to achieve this.
You need to inject into the process, that is the only way to add a menu item.
A shell hook will notify you with HSHELL_WINDOWCREATED when a appropriate window has been created. You can then inject into the process (with another hook type or CreateRemoteThread). Once you have your .DLL in the process you can subclass the window and change the system menu.
You need to create both a 32-bit and 64-bit injection .DLL and I would recommend that you write it in native code, not C#.
I'm trying to make an OS X app, and for some reason, I can't find anything on how to add items to the Main Menu (File, Edit, etc), and how to actually handle those actions. Everything I've found is how to implement a Status Bar application, which is not what I want. Can anyone help?
The menu bar is part of your application's MainMenu.nib, and can be edited there. Like other user interface objects, each menu item has a target which can be configured to control what it does.
A video tutorial is available here. (I'm not usually a fan of videos, but this one is so perfectly on-target that I'm making an exception.)
I know nothing about AppleScript, but I wonder if it could make my life easier: is there a way to write an AppleScript that tells Safari / Firefox / Chrome to refresh the current tab when I save a document in another application, say TextWrangler? Essentially, I want to map the Command+S keyboard shortcut to do two things at once in two separate applications.
If that’s not possible, can you script one application so that saving one file executes a command in another window in that same application?
There are different possible approaches to implement this, but the most straightforward would probably be to create a script that executes all steps you need (i.e. save the document and refresh the window) and bind that to the Cmd+S keyboard combo in the triggering application.
What you need for this approach to work, is, in order:
a method to bind a key combo to a script effective only in a specific application. OS X’ Automator Services fit that bill: their scope can be restricted to a single application (select it in the “only in” drop down at the top of the workflow actions), and they can be assigned a shortcut in the Keyboard preference pane of System Preferences.
a way to relay your commands to the applications they target. AppleScript can help you in two different ways, depending on the fact if your applications are scriptable, i.e. if they have a scripting dictionary you can inspect in the AppleScript editor:
if they do, and their terminology includes the saving action for the editor on one side (most scriptable document based apps do so in the form save <document>), the page refreshing for the browser(s) on the other (Chrome has reload <tab>, Safari gets the same result via a JavaScript detour, i.e. do JavaScript "window.location.reload()" in <document> – I don’t use Firefox), you are set.
if they do not, GUI Scripting might help, i.e. simulating a click on the right UI element (menu or toolbar) via tell application "System Events" to tell process <your process> to click item x of menu y.
That script can then be embedded into the Automator workflow (in an “Run AppleScript” action, to be precise).
As you can see, a lot depends on the exact software you are using. if you are new to AppleScript and the above baffles you, I’d suggest spending a bit of time on the AppleScript pages of Mac OS X Automation (where you’ll also find example scripts which will kick start you into things like GUI Scripting).
One final note: as of this writing, sandboxed applications do not honor key combos assigned to them in the Keyboard Preference pane (they do honor global key combos set there – just not those specifically targeting them). This means you cannot, for instance, currently override TextEdit’s Cmd+S shortcut for saving in Lion. As long as your editor is not sandboxed (easily checked in Activity Monitor), you should have no issue with this.
One solution would be to create a folder action to refresh the current tab when a new file is saved in the folder.
on adding folder items to theFolder after receiving theFiles
tell application "Google Chrome"
activate
tell window 1 to tell active tab
set URL to (get URL)
end tell
end tell
end adding folder items to
I am using LSOpenItemsWithRole() to open any file from my application. It works fine for all files which has a default application on Mac, but for the files which cannot be opened with any default application this method returns an error kLSApplicationNotFoundErr and does nothing.
For such cases, I want my application to launch the "Choose Application" dialog box, so that end users can choose any application from there to open the file. This dialog box pops up whenever any such file is directly opened by double clicking. Is there is any direct API call to do the same?
I don't want to use Objective C call, is there any way to do it using Carbon API calls?
You should use an NSOpenPanel, starting the user in the Applications folder use and the panel:shouldEnableURL: delegate method to filter out paths that don't end in .app. You can use setAccessoryView: to add any custom options to the dialog. This is what the Finder is doing when you click on the "Other..." option when selecting which application to use.
I think you can do it by using NavCreateChooseFileDialog, with NavCustomControl to set the initial location and NavDialogSetFilterTypeIdentifiers to filter out non-apps. (Why don't you want to use Objective-C? You know that you can mix Carbon and Cocoa in one app, right?)
From the Displays pane in System Preferences, I can manually change the main monitor by dragging the menu bar from one display to the other. I'd like to automate this and make it part of an AppleScript.
The tool I wrote, displayplacer, does this.
Configure your screens how you like, drag the "white bar" to your primary screen in the macOS system settings, and then execute displayplacer list. It will output the command to run to put your screens in their current configuration. The screen with origin:(0,0) is the main display with the "white bar". Run this terminal command through a script, Automator, BetterTouchTool, etc.
Example profile 1 puts the white bar on the menu bar on the left monitor.
displayplacer "id:<leftScreenId> res:1920x1080 scaling:on origin:(0,0) degree:0" "id:<rightScreenId> res:1920x1080 scaling:on origin:(1920,0) degree:0"
Example profile 1 puts the white bar on the menu bar on the right monitor.
displayplacer "id:<leftScreenId> res:1920x1080 scaling:on origin:(1920,0) degree:0" "id:<rightScreenId> res:1920x1080 scaling:on origin:(0,0) degree:0"
Also available via Homebrew brew tap jakehilborn/jakehilborn && brew install displayplacer
The displays are controlled by the /Library/Preferences/com.apple.windowserver.plist preference file:
A flag controls whether the main display is the onboard screen the DisplayMainOnInternal key.
The DisplaySets key contains the list of the display sets. The first set is the one used (fact to check).
In the set, each item contains the screen properties. The IOFlags key seems to indicate if the display is the main one (value of 7) or not (value of 3).
Before going Apple Script, you may change the display configuration by hand, and save a copy of the /Library/Preferences/com.apple.windowserver.plist file to study it.
Note that the following procedure has not been tested !!!
With AppleScript, the keys in the plist file are changed individually, in order to change the main display:
Make a backup of the /Library/Preferences/com.apple.windowserver.plist (in case of)
Alter the display set the select the main display (DisplaySets and IOFlags keys) by using the defaults command
Restart the Window Server: killall -KILL SystemUIServer
You should see if you can do it via AppleScript's User Interface Scripting. It allows you to manipulate an application's GUI elements; useful when the app doesn't support scripting directly. I'd test it myself but I don't have any extra displays lying around.
Here's a pretty good overview by MacTech.
Much like you can tell System Events.app to sleep your Mac, you can tell Image Events.app to mess with your displays. The Image Events application provides a "displays" collection. Each display has a "profile" with lots of goodies. However, everything I just mentioned is read-only, so I don't have a good way to do it from within script.
You might have better luck in Automator – Hit record, run System Preferences, go to Displays, drag the menu bar to the other screen, and hit stop. I bet something will work.
Using AppleScript, you can invoke default to write the setting to change the main monitor.