How to write an OS X application that can effect changes (custom cursor, draw an image) even when it is not active? - cocoa

I previously asked a question about changing the cursor system-wide on OSX. I used NSCursor to change the cursor, but the effects are only as long as the application is active. When another application becomes active, the custom cursor is lost.
Here is a related, more general question. How can you write an application to have system-wife effects? For example drawing an image on-screen even when your application is not active, and something else is?
I understand I probably need to go at a lower level than the Cocoa APIs. I just cannot figure out where to start looking? Any specific Carbon APIs that I need to be looking at? Or even lower?
Any pointers would be appreciated! If you specifically know how to change the cursor system-wide or how to draw an image and move it around (no matter what application is active), that would solve my current problem as well! Can I write an application that can achieve this when its installed on the system?
Thanks!

You can achieve the effect you want, but not the way you're thinking about doing it.
You say,
I am writing a presentation aid application that shows the equivalent of the "laser pointer" on screen, programmatically. My first idea was to use the mouse cursor itself as the pointer, and change its appearance as a red circle.
Then fake that. Create an application, perhaps of type LSUIElement, perhaps not, depending on the behavior you want. Create a borderless window (type NSBorderlessWindowMask) and fill it with a clear color. Set its window level high enough so that it floats over everything (using -[NSWindow setLevel:], though I can't think of what the best level would be off-hand), and draw into it.
It's true that you cannot set the cursor when you are not the foremost app. It's true that you cannot just scribble on the screen. But you can get the same effects if you're clever.

This behaviour is not provided by any APIs on Mac OS X. You would have to modify the resource files in the OS, and that's a very dangerous operation that could brick the target computer. You have to know what you're doing.
Are you trying to implement a theming app or something like that? What's your goal? If you tell us what you are trying to do, we may be able to suggest alternate approaches.

Related

Painting data from device context

I've just got a fresh device context (DC):
GetDC(someForeignHwnd)
Most normal people now want to paint on this. I don't. I want to display the context in my own program. Or duplicate, I wouldn't even mind the window I stole the context from beeing empty.
In my case, I want it in a TPanel in Delphi, but anything else helping me understanding goes.
Afterwards, I'll probably find the DC invalid by the time I get to display it.
My main problem is: Showing the content of another window in my own. But that isn't important. First of all, I want to know how these DC are of any use. Can I do something like the following?
Canvas.Draw(0, 0, MyNewDC);
The answer can be in Java, C, or Pascal. Is it just not possible or just a stupid idea?
While it's possible to use a device context that you retrieve via GetDC() as the SOURCE for BitBlt(), etc., you will likely not get the results that you're looking for. When you call GetDC() for a specific window, Windows essentially returns a device context for the screen, but with a clipping region set to exclude any portions of the screen where the window is not visible. For example, if there happens to be another window overlapping the source window, the portion of the source window that is covered is clipped from the device context. Therefore, you can only "retrieve" the bits that are actually visible.
You may have better luck sending a WM_PRINT or WM_PRINTCLIENT message to the window. However, not all windows respond to these messages, so this isn't a universal solution.

How to create an invisible X11 window for GPGPU?

Is it possible to create an invisible X window? For initialization of an OpenGL ES 2.0 context, one has to create a X window manually, but I can't find a way to make it invisible. Since I'm only doing GPGPU I don't need an output window. In fact, it is rather annoying in my case.
I'm aware of a solution from an earlier question, where it has been pointed out to use InputOnly in XCreateWindow(). This, however, leads to the X error GLXBadDrawable. Probably because EGL requires the window to respond to graphics request. Is there another way? Maybe create it minimized? But I can't find anything on that either. Also setting the window's size really small doesn't help, since it always occupies the whole screen on my device (Nokia N9).
When you create an X window, it is created unmapped, so what about creating an InputOutput window and leaving it unmapped? Another option would be (if the window must stay mapped), to move it out of the screen.

Draw over screen with Quartz

I'm trying to work out what the best way to draw over the top of all other items on the screen on OS X. I don't want to impede the user's ability to interact with their applications, but want to 'annotate' them. I want to be able to draw up to 20 different annotations. The top half of this screenshot from Gizmodo happens to nicely show the kind of thing I want to do. http://gizmodo.com/assets/resources/2006/07/04%20Safari.jpg (sorry, I'm too new to post it as an image)
The questions I think I need to answer are:
Should I create a single window for
each drawing and draw to that? If
so, how do I minimise overhead?
What kind of window or other context should I use given that I don't want any window
decoration?
I don't think I want the overhead of creating 20 windows, but I also don't know that I want to create a full-screen, invisible window that contains my context (I presume a subclassed NSView), because I fear that will a) cause problems interacting with what's below and b) break the niceties of only redrawing when necessary (my actual drawing will likely only cover 10% of the screen)
I've not worked with Quartz2d before, so I just can't get my head around how to get the 'right' context to draw on from the documentation. Any help would be appreciated.
Thanks,
Who
You can only draw into a window. You can make a transparent, borderless window but it will need to be at the front.
You could set it's level to something like NSPopUpMenuWindowLevel to make it draw above other windows (this will be very annoying to users) but clicking on it will:
a) activate and bring to the front your app
b) Prevent the app underneath receiving mouse events
Is that what you want?

Updating the region behind a resized window

We have a fairly complex GUI, so when certain windows are resized their Redraw() is set to false till the operation is completed. The problem with this is that if the OS "Show window content while dragging" setting is checked, when decreasing the window's size the windows behind it are not repainted. This means I have to force the repaint myself so the remains of the resized window are deleted. I have no problem getting the dimensions of the region that was uncovered. What I'm looking for is best way to cause all windows within that region to repaint their part.
Not being much of a GUI programmer, I can traverse the uncovered region and list the windows in it. Then, I can ask each one of them to repaint its part. But I'm quite certain there has to be a better way to do this...
It is worth mentioning the app is written in PowerBuilder. This means I can call whatever Win32 function I'd like, but have limited control over the GUI behavior and the message handling. If there's a better way to prevent the window's content resize from being visible, or there's a way to make a non-redrawn window clean after itself, I'd love to hear it (just have the limitations above in mind).
I'm curious what version of PowerBuilder you are working in? I do resizing all the time and never run into issues like you are describing.
Maybe you can lay out some more detail on why you need to set your redraws to false within the PowerBuilder environment.
Hope I can help.

Implementing "scrubby sliders" in Cocoa?

How would I go about implementing something along the lines of "scrubby sliders", like in Photoshop and quite a few other image-processing applications?
They are slightly hard to describe.. basically you have a regular numeric input-box, but you can click-and-hold the mouse button, and it functions like a slider (until you release). If you click in the box, you can select text, edit/paste/etc as usual.
The Photoshop docs describe it, and I put together a quick example video (an example of the sliders in Shake)
Another similar implementation would be the jog-wheel in Final Cut Pro, which functions similarly, without the numeric readout being underneath.
I can't seem to find any mention of implementing these, although there is probably alternative names for this. It is for a OS X 10.5 Cocoa application.
It is for a colour-grading application, where a user might need to make tiny adjustments (0.001, for example), to huge adjustments (say, -100 +100) on the same control. A regular slider isn't accurate enough over that range of value.
Copy-and-pasting values into the box would be a secondary concern to scrubbing the values, and the Photoshop/Shake setup really well. The unobviousness of the control is also of a low concern, as it's not a "regular desktop application"
I've encountered those. They suck, because they prevent the user from dragging to select the text of the number.
A better idea would be a miniature slider beneath the field that expands to a full-size slider when the user holds down the mouse button on it and collapses back to its miniature size when the user releases the mouse button. This way, the selection behavior is still available, but you also provide the slider—and in a more obvious way.
There's no built-in class in Cocoa for either one. You'll have to implement your own.
I doubt that this exists in Cocoa framework. As far as I remember it is not mentioned in the Apple Human Interface Guidelines.
You can develop one yourself by using a custom view and tracking mouse events (-mouseDown:, mouseUp:, -mouseDragged:).

Resources