How do I receive notification of a new window opening? - cocoa

I want to respond to a certain type of new window being opened by an external application. I have some experience finding applications and windows currently open (system wide) using some of the carbon functionality, so could theoretically just check every few seconds. This would require getting a list of all open windows and checking it against some list I would have to maintain, and feels very clunky.
How can I get a simple, clean notification when a new window is launched? Should I use the accessibility API? If so, what specifically am I looking for?

First, create an AXObserver. Then, watch for launches of any applications that you think you'd be interested in. When such a launch occurs, create an application AXUIElement for that process, and add your observer to it for the kAXWindowCreatedNotification notification.
I question whether this is the best way to do whatever you're trying to do. You might step back a bit from this solution (that is, watching for new windows) and ask another question about your goal.

Related

Keep Chrome Shortcut running in Windows Background

I' building a webapp that reads the database based on time to check changes. When there is a change, a notification in windows displays so the user is notified.
Chrome-> Dots menu-> More settings-> Create shortcut (as window) (Roghly Translated)
The problem is that the user needs to have the webapp opened so it is working and doing the before mentioned task. I thought a solution could be to run the shorcut on startup as a service or something (maybe in the icons next to the taskbar clock). But I don't know if this is the best approach or how to do that.
That's why I'm asking for help to find the best approach and if it is the one I'm thinking, to know how could I do that.

Intercepting a window's attempt to steal global focus on Windows

I'm a developer and a long-time Windows user with an obsession about making my system as convenient to use as possible.
Yesterday I thought about something that has always annoyed me in Windows and that I've taken for granted, and I realized that I have a better idea for how it could work, and I'm now wondering whether it's possible to tweak Windows to work like that.
The thing that annoys me is when windows steal focus. For example, I could be running an installer for some program. While it's working, I'll switch to my browser and browse, maybe entering some text into an email in my browser. Then suddenly the installer finishes and its window steals the focus. Now I'm in the middle of writing an email, so I might press a key that happens to be bound to a button on that installer, and then that button gets invoked, doing some action that I never intended to happen!
This is doubly annoying to me because I'm using a multiple-desktop program called DexPot, and when a window steals focus, it also brings itself to the desktop I'm currently on, which can be really annoying, because then I have to put it back into its original desktop.
How my ideal solution to this problem would work: Every time a window tries to steal focus, we intercept that, and don't let it. We show something like a toaster message saying "Foobar installer wants focus, press Win-Whatever to switch to it". If and when you press the key combo, it switches to the window.
The question is: Is there an easy way to tweak Windows to make this happen? I know very little about Windows programming. I do know AHK and if it's possible with that, that'd be great.
No, there isn't an easy way to add this behavior, but Windows tries to do this automatically.
In theory apps shouldn't be able to steal the foreground while you're actively using another app. Unfortunatly there are some scenarios where Windows can't tell the difference between legitimate user actions that should change the foreground and unwanted foreground-theft. The window manager generally tightens up the holes a bit with each new version of Windows, but also needs to make sure that apps can come to the foreground when the user wants them to, even if that desire is expressed indirectly.
For example, a process launched by the current foreground process can put a window into the foreground. This is necessary so that when a user launches a window from Explorer the newly launched process can open its main window. This permission only lasts until the next user input, so if an application is slow to launch and you start working on an email the app may lose its foreground permissions before it can use them.
See the SetForegroundWindow function documentation for a list of requirements for a process to be able to set a window into the foreground.
There are also apps which specifically make use of these requirements to steal the permission (by joining the foreground queue or synthsising user input to themselves), but I suspect in your installer scenario it is accidental.
I'm not sure what exactly is going on, but I suspect that the problem comes from the installer running as a service and accidentally stealing the foreground permission when it tries to launch the app on your current desktop.
It would be theoretically possible for an external process to hook into the foreground system to override this and show your confirmation toast, but it would be tricky to get right and would require significant low level code (I'd probably start with a CbtHook). It would not be possible in a scripting package like AHK (assuming you mean AutoHotKey) but would need to be native C/C++ code injected into every running process.

Closing delphi app along with another application it opened

I have an application that called several other .exe components written in delphi. The question I ask is that is it possible to close the delphi app along with all application it opened (when clicking the '[x]' button)?
Also, obviously, I have learned how to open and close external application, but in several cases like Windows Media Player it just doesn't seem to work... can anyone give me some solution to this?
Thanks in advance
You can use Job Objects , read the documentation for these functions CreateJobObject and AssignProcessToJobObject.
A job object allows groups of processes to be managed as a unit....
Examples include enforcing limits such as working set size and process
priority or terminating all processes associated with a job.
If you keep track of the applications you open, you can post a WM_QUIT message to each one's window handle in the OnClose event of your Delphi app's main form.
The same should work for Media Player, but it's hard to say when you don't give any information about how you opened it.

new Windows 7 systray - how to show information to users now

new Windows 7 hides systray icons by default.
what is the recommended way to show information to users now?
I need to have a small clickable icon visible to user so user can access my "tool" anytime. Should I use the gadget to show my GUI instead? Can it communicate with my Delphi app somehow?
Without more information it's a little difficult to provide a recommendation.
However, I would imagine that a sufficiently important tool, the user would simply keep minimized. They could then use Jumplists to access quick functionality.
For example, Live Messenger uses this setup on Win7.
If your users really like your icon/application they can always choose to not hide your application.
The only difference is that only the user can choose which icon is shown, instead of every application claiming it's "real estate".
In my opinion this is a good functionality and if I were you I wouldn't change the application, just provide a first run GUI which explains how to make your tray icon visible in windows 7.
The entire reason why change was made, was to stop programs like yours. If you need to show information, go ahead and do so. But the notification areas ("systray") is not where shortcuts go. For that, you've got the start menu, desktop and/or the quick launch bar (and please let the user decide).

How can I post a Cocoa "sheet" on another program's window?

Using the Apple OS X Cocoa framework, how can I post a sheet (slide-down modal dialog) on the window of another process?
Edit: Clarified a bit:
My application is a Finder extension to do Subversion version control (http://scplugin.tigris.org/). Part of my application is a plug-in (a Contextual Menu Item for Finder); the bulk of my application, however, is in a separate daemon proces. For several reasons, we've chosen to put virtually all the code into the daemon; the plug-in only defines the menu itself, and Apple-Events over to the Daemon.
Sometimes, the daemon needs to prompt the user for further information. It can toss a window on-screen for this, but that's disruptive (randomly positioned), and it seems to me the work flow here is legitimately modal, for example "select a file, pick 'commit' from the menu, provide commit comments, do the operation."
Interprocess cooperation (such as passing a reference of some kind) is acceptable: both processes are mine, but I want to avoid binding the sheet's code into the primary process.
Really, it sounds like you're trying to have your inter-process communication happen at the view level, which isn't really how Cocoa generally works. Things will be much easier if you separate your layers a bit more than that.
Why don't you want to put the sheet code into the other process? It's view code, and view code is inherently process-specific. The right thing to do here is probably to add somewhat generic modal-sheet support to your plugin code, and an IPC call that your daemon can make to summon that code. Trying to ship view objects over to the remote process is going to be nightmarish if you can make it work at all.
You're fighting the frameworks with this approach.
You can't add a sheet to a window in another process, because you have at most only the most restricted access to the windows in the other process.
Please don't do this. Make the interaction nonmodal if at all possible. Especially in something like a commit, it's much nicer to be able to browse around your files while you're writing commit comments.
OS X does have window groups, but I don't think they can (easily) span applications.
Another thing to consider is that in OS X it's possible to have many Finder windows open on the same folder (unlike in OS 9). Even if you did have sufficient privileges/APIs to add a sheet to a Finder window, it's not like the modality of that window would prevent the user from being able to continue working with the files.
(My personal opinion as a long-time Mac user is that this kind of interaction would drive me right up the wall.)

Resources