cinder/Cinder — pull request #378 by nselikoff (2013-09-10 19:04:21+00:00)
Title: Responding to a window becoming active or inactive

For one of my projects, I need to know whether my app's window is active or inactive, so I can stop some expensive calculations in the latter case. As far as I could tell, this isn't directly possible with Cinder as-is (but someone please correct me if I'm wrong!)

### Single window apps

In this branch I've implemented two new callbacks, `App::activate` and `App::deactivate`, with associated signals. They are pretty self explanatory; `activate` will get called once when a window becomes active, and deactivate() will get called once when a window becomes inactive (e.g. if you minimize it, alt+tab or command+tab away from it, or otherwise change the OS's focus to a different window). The callbacks are useful for single window apps and look like this:

```c++
class MyApp : public AppBasic {
...
void activate();
void deactivate();
};

void MyApp::activate()
{
console() << "window activated" << endl;
}

void MyApp::deactivate()
{
console() << "window deactivated" << endl;
}
```

I've also added a Window::isActive function so you can query for the state of a window at any time. This just checks a boolean, mActive, whose value is set when the OS specific messages are processed. So you can call `getWindow()->isActive()` (or via `getWindowIndex`) whenever you need to.

### Multi window apps

To get window specific activate/deactivate signals, you can mimic the BasicAppMultiWindow Cinder sample. In the `createNewWindow` function:

```c++
newWindow->getSignalClose().connect(
[uniqueId,this] { this->console() << "You closed window #" << uniqueId << std::endl; }
);
newWindow->getSignalActivate().connect(
[uniqueId,this] { this->console() << "You activated window #" << uniqueId << std::endl; }
);
newWindow->getSignalDeactivate().connect(
[uniqueId,this] { this->console() << "You deactivated window #" << uniqueId << std::endl; }
);
```

### Known Platform Differences and Quirks

I kept it pretty simple and tried to follow the pattern of what's already there. For the Cocoa implementation, I added observers for `NSWindowDidBecomeMainNotification` and `NSWindowDidResignMainNotification`. For the MSW implementation, it's responding to `WM_ACTIVATE` and `WM_ACTIVATEAPP` messages.

I've tested on both OS X 10.8 and Windows 7 with a single window Cinder app, and OS X 10.8 and Windows 8 with a multi window Cinder app.

In my testing, it seems that when a window first opens it doesn't reliably get the OS's "activate" message. Since we explicitly set the newly created window as active, I have set the active flag appropriately so a new window is active by default.

I also noticed that when closing a window on OS X, I'll only get a "close" signal, whereas on MSW I'll get both a "deactivate" and a "close" signal.

Finally, OS X has the concept of a "key" window as well as a "main" window (see [this link](https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/WinPanel/Concepts/ChangingMainKeyWindow.html#//apple_ref/doc/uid/20000236-BCIDFJFH) for details). Do we care about the key window for a feature like this?

Original forum post: http://forum.libcinder.org/#Topic/23286000001719041