Force window to front/focus? - macos

I'm writing an MacOSX bundled app in GLFW.
When the window pops up, I want it to be on top of all the other windows. I also want it to grab focus (I'm coding in vim, and I type ":make run" -- and I after that, I want to interact with the app).
Question:
1) Is there some API call I can use to make this happen?
2) Is there some configuration I can do in MacOSX to say something like "the program named blah, have it steal focus on startup"?
Thanks!

The cocoa API is [NSWindow makeKeyAndOrderFront:] there's probably something similar you can do from your library.

If you wrap your built executable in a application bundle, then you should be able to open it in the terminal (e.g. via the open command) and the focus will automatically switch to it.
Note that you will probably need to package your application in a bundle anyway.
First, you need to package it because that is what the GLFW FAQ says.
I personally found this to be necessary because, at least in GLFW currently available on github (commit 3e78), atop Mac OS X 10.7.5, the keyboard handling is stolen by the terminal if you don't have the executable sitting in an app bundle.
I witnessed the keyboard-input-stealing behavior occurring even when I manually switched the mouse focus to the window that popped up when I ran the binary. That is, the keystrokes I typed still ended up in the terminal window.
You can test this behavior yourself on your own system by taking one of the example apps for GLFW, like Triangle.app, copy its binary to a different directory, like /tmp/, and then run the binary from there. Here is a demonstration of the distinction I am making.
% pwd
/Users/pnkfelix/Dev/OpenGL/glfw/objdir/examples/Triangle.app/Contents/MacOS
% ./Triangle
(The open command works too:)
% open ../../../Triangle.app
In the above scenarios, hitting ESC with the triangle window focused made it quit, as expected.
However, the problem comes when the program is not sitting in an bundle:
% cp ./Triangle /tmp
% /tmp/Triangle
^[^[^[^[^[^[^
In this scenario, hitting ESC with the triangle window focused passed the keystroke to the terminal window that launched the program. (That is what the ^[ glyphs are -- the terminal responding to the ESC keystrokes it has received.)
The good news is, it is relatively easy to wrap a built executable in a bundle.
For example, when I was doing other experiments with binding the GLFW library, I found the following Makefile rule sufficed for constructing a makeshift bundle from an executable:
test: Triangle.app
open Triangle.app
Triangle.app: Triangle.app/Contents/MacOS/Triangle
Triangle.app/Contents/MacOS/Triangle: triangle
mkdir -p Triangle.app/Contents/MacOS
cp $< $#
(note that the 8-space indented commands above should not be copied verbatim, but rather rewritten as tabs as required for Makefiles).
However, please note that the above Makefile rule is not the official structure for application bundles, and shouldn't be trusted for anything except personal experimentation. Apple has the documentation on how to officially package your application in a bundle, so you should take the time to do whatever steps they describe before you release anything you produce into the wild. (For example, the Makefile rules listed above make no attempt to generate an Info.plist file, which is one of the required components according to Apple's documentation.)

Related

How to use Vim in a part of Terminal with Go

I'm trying to create TUI app with Go.
I'll make this app like dashboard.
And I want to use Vim as a part of Terminal(iTerm2) screen.
And I want to use local vim env(NeoVim, Local vimrc and plugins).
How do I use local vim with go?
Or are there go libraries to use local vim?
My English isn't so good so feel free to ask me if there is anything unclear.
Thank you.
What you're trying to do is inordinately difficult to do, and I would advise against it.
The only way to embed a terminal application like you're describing is to essentially implement a terminal emulator within your application and display its output within your application. There are libraries which can make this easier -- like libvterm, which vim uses to implement the :terminal command -- but even so, doing this will be difficult, particularly if you want to support advanced terminal functionality in the embedded editor (like mouse support).
A more common idiom for making an editor available in a terminal application is to launch the editor as a subprocess on demand, allowing it to "take over" the entire terminal while a file is being edited. Once the editor exits, your application can resume.

Do executable files always open a terminal window on MacOS?

I'm on MacOS X, and I'm pretty new to app-bundle-type things. I am writing a program that opens a window and registers mouse input -- not a command line tool. When I compile my code (written in C, if that is important) into an executable file (a "unix executable file") and then run that file directly (by double clicking it, for example), a terminal window pops up, and then the program's window pops up. Likewise, if I navigate to the directory of the executable and open it from the command line, it pops open /another/ terminal window and then the program's window.
However, if I wrap the executable in a bundle (thus, I suppose, turning it into a proper "app"), then when I run the app, either by double clicking or from the command line, the program's window opens and no new terminal window is created. Is this merely a property of the "app bundle"'s architecture? Or is there a way that I can run the raw executable without incurring another terminal window? I suspect that I'm misunderstanding something fundamental. Thanks in advance!
I believe what you're seeing is correct. In order for a separate window to not pop-up, you'd need to encapsulate it into a bundle.
Launching by double-clicking a bundle, or using the 'open' command from Terminal uses Apple's Launch Services, which maintains a list of known (registered) applications. When an application (bundle) is introduced to the system, it is registered with Launch Services and associated with its URI (e.g. com.apple.calculator), which is present in the bundle's Info.plist
Other items in the Info.plist tell launch services how to handle the application, such as checking if the minimum or maximum version of the OS has been exceeded, or whether or not to display a dock item.
A lone binary doesn't have an associated Info.plist manifest, so its behaviour can't be varied and a Terminal window is opened.
Bare executable files are essentially treated as documents by Launch Services (the framework that the Finder, Dock, and open command use when you open stuff). The application which handles such documents is Terminal. So, when you open an executable in that fashion, it launches Terminal if it's not already running and tells it to open the document. Terminal does this by opening a new shell window and auto-typing the path to the "document" as a command line.
Launch Services handles bundled apps as, well, apps. If the app is already running, it activates it and possibly has it open a new untitled window. Otherwise, it launches it.
As Rob Napier notes in the comments, if you run an executable directly from the command line (or if some already-running app launches it using NSTask or fork+exec), it will simply run. Launch Services won't be involved, so Terminal will not be asked to open the executable as a document.

Can a Cocoa app's executable steal focus from caller?

Say I have a standard Cocoa Application call Foo.app (like the one you get just by choosing New Project > Cocoa Application in Xcode), if I open the app via a terminal using:
open Foo.app/
Then I see Foo's name on the status bar up top and its window is in focus, in front of all other apps.
If instead I directly call from the terminal the executable buried in the .app folder, like:
Foo.app/Contents/MacOS/Foo
Nothing appears to happen. On inspection the app has indeed opened but it is not in focus (the terminal still is), I have to find it on the dock or find its window.
Is there any way for the Foo application to make sure its in focus when its run? Even if its run via its executable as described above?
Your app can "steal focus" by calling
[[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
See the NSApplication docs for more info.
did you mean to type:
open -a /Applications/Foo.app/
note the -a option
If you're asking how to give your app (that you're writing) this behavior -- within applicationWillFinishLaunching: you could call [NSApp activateIgnoringOtherApps:YES].
perhaps AppleScript?
tell application "TextEdit"
activate
end tell
There are (at least) three different ways you open (and interact with) Applications from the Terminal.
you can launch any Application (that is registered in LaunchServices) from the Terminal by typing open -a ApplicationName (note that you do not need the trailing ".app" or give any path)
you can open an application giving its specific path by typing open /path/to/ApplicationName.app (you will rarely need that, given that the applications is likely already registered in LaunchServices)
you can open and interact with the executable if you type open /path/to/ApplicationName.app/Contents/MacOS/ApplicationName. The difference here is that for some Applications, you can pass arguments or interact with them afterwards on your command line. Go ahead and try open /Applications/Mail.app/Contents/MacOS/Mail for example - it will give you a debugging log in return.
you can interact with some applications even without using "open" by directly calling their executable; try /Applications/Firefox.app/Contents/MacOS/firefox-bin —help for example.
So if you do want to make sure the command-line-launched application is in focus, use either method 1 or 2.

GTK: How to ignore "can't open display" errors?

I have written some GTK programs using the gtkD bindings for the D programming language that are otherwise console apps, but are capable of displaying plots on the screen and saving them to a file. I'd like to run these on a machine that I only have console-based SSH access to, which means that the plots wouldn't be displayed on the screen, but would still be written to files.
When I call Main.init(), I get a Gtk-WARNING **: cannot open display, as expected. When I call Main.initCheck() instead and ignore the errors, I simply get more errors later in execution related to the lack of a screen.
Is there some easy way to make my program ignore the fact that there's no screen available, do all its on-screen drawing to some dummy device (the graphics equivalent of /dev/null) and still actually draw to Pixmaps and Pixbufs (necessary for saving plots to files) and run the non-GUI-based parts of the app?
Edits: In cases where the app launches a window and blocks on an event loop, the ideal thing to do would be to close the window immediately (or not succeed in opening it in the first place) and continue running the non-GUI based parts of the program. If this is impossible I can work around it by making sure I don't launch any windows.
Also, it appears that Pixbufs and Pixmaps don't work without a screen present. I tried drawing to a Pixmap, creating a Pixbuf out of that, and saving the results to a file, either after calling Main.checkInit() and ignoring the errors or without an init statement and either way GTK complains about lack of a screen.
I believe the simplest solution is to use only GdkPixbufs for processing your plots; as far as I know, the gdk-pixbuf library only deals with pixbufs in memory and doesn't need a window system. Keep the processing and display parts of your code strictly separated. If you do that, it shouldn't matter that there is no screen. You could even make a command-line option to disable drawing to the screen.
You could also use GtkOffscreenWindow but this has only been available since GTK 2.20 and as far as I can tell the D bindings only cover up to 2.18.
Alternatively, you could use X forwarding in your SSH session; use -X or -Y on your SSH command line. See your SSH manual for more information. If you are running an X server on the machine you are SSH'ing from, then the plots can be displayed on your local machine's screen.
Pixmaps won't work without server - they are, by definition (in X terminology), image resources stored on X server. Pixbufs, however, are stored in client application, and they should work without X.
If you need Pixmaps but don't want to graphics, you have two choices:
Enable SSH X tunneling by passing -X flag. In this case, your app will be able to use local X server.
Use Xvfb - it's dummy X server that does no output at all, and all graphics are stored in memory.

Emacs talking to XCode

I use emacs on my mac to program in Xcode. It works really well for the most part. I double click on a file in xcode, and it pulls it up in an existing emacs window. I compile, and get syntax errors, double click, and they come up in the active emacs window. great.
This is all XCode talking to emacs. Does anyone know of a way to get emacs to talk to XCode? For example, I want to be able to set a breakpoint in emacs and have the XCode version of gdb acknowledge it.
You can actually use AppleScript to set breakpoints in XCode from within Emacs by embedding the AppleScript inside of elisp.
This page contains the code you need. It's in Korean, but there's actually not much Korean to understand. The first code block is just a straight AppleScript example that was used to develop the breakpoint code. The second block is the one you want. It embeds the first example in an elisp snippet that you can add to your .emacs file.
Other communication can be done using the same trick. Just figure out how to do what you want in AppleScript and then embed that AppleScript in elisp within Emacs.
BTW, here is the documentation for do-applescript, the lisp function, available on the Mac, that lets you call AppleScript.
Sounds like a job for a new plugin!

Resources