In Lua Hammerspoon script, how to draw on a specific desktop? - macos

I don't see any APIs to enumarate desktops or move drawing to a specific desktop.

As the documentation always names THE desktop and desktop does not have any window id nor subrole I assume Hammerspoon does not support multiple desktops?
Hammerspoon seems to treat desktop as one of a kind top level window object.

Related

How to figure out which application window is on the top?

I am a noob when it comes to Desktop GUIs. Is there a way for me to programmitically figure out which application window is the top most in terms of display environment?
So, basically, I can have a process running in the background, that might then change the behavior of the top-most (or say the selected) window. My go to operating system would be MacOS (then Linux family). Also, for instance, there is an app called spectacle app, which listens to key bindings to snap resize and move active windows on MacOS.

What is 'Desktop Presence'? (As used in the Windows UI style guidelines)

A lot of the Windows style guidelines refer to 'Desktop Presence' in various places, e.g. http://msdn.microsoft.com/en-us/library/windows/desktop/dn742496(v=vs.85).aspx', but it's never defined anywhere that I can see.
Is there a definition for what exactly they mean by this?
Is it the presence of a normal window on the screen throughout the execution of the application? Do apps that occasionally appear on screen (with dialogs or notifications), but are predominantly hidden count? What about applications you can interact with on the desktop but only on demand, e.g. the wireless network connection menu?
Found an ok answer in the article I initially linked to, in the end (http://msdn.microsoft.com/en-us/library/windows/desktop/dn742496(v=vs.85).aspx):
"The taskbar is the access point for programs displayed on the desktop, even if the program is minimized. Such programs are said to have desktop presence."

Mac OS X / Open terminal with specified windows *on specified desktops*

The accepted answer to this question explains how to create a "window group" in Terminal.app so that you can open a set of windows with predefined tabs executing predefined commands in predefined positions.
That's great, but it doesn't appear to play nice with Mission Control. I save my window group with the windows spread out across different desktops in Mission Control, but when I restore the window group they all pile up on top of each other in the desktop I'm currently using!
How can I get a Window Group to restore the windows to the desktops from which I saved them?
Thanks!
Doesn't look like separating application windows by desktop is an option anymore; not according to this MacForums thread.
There's an app called TotalSpaces that claims to restore pre-Mission Control window grouping, but it's a paid app so I haven't tried it.
You might be better off asking this question on AskDifferent or SuperUser...

Does Windows 7 treat full-screen applications differently?

I have a hidden process that waits for non-standard hardware button messages and runs an application (with CreateProcess). No problem with the user disturbing, it's an action that the user approved himself. Everything is fine when it's usual layout with taskbar shown and multiply captioned and non captioned- windows. But the situation is different in XP and 7, when the current application is full-screen. Full-screen application in this case is window without borders having exactly the same dimension as the screen. Windows hides taskbar for such application even if it's always on.
In Xp, it's ok, the taskbar is being shown in this case and appication (for example calculator) also, the full-screen app is still visible in areas other than the launched app's and taskbar'. But in Windows 7 nothing visual happens, the full-screen app is still on and if I switch to taskbar, the executed application is there. I tried to solve it with SetForegroundWindow, BringWindowToTop, even AllowSetForegroundWindow(GetCurrentProcessId()) call for a window handle found with CreateProcess-WaitForIntputIdle-EnumThreadWindows, no change. So did something change since XP related to full-screen windows that officially documented?
Thanks,
Max
I would imagine that, if you have your own hardware device, that there is some API for generating "real" user input. Clearly the legacy keyboard and mouse, and now USB HID drivers (many of which are usermode I think?) have access to an API to do so.
Synergy+ for example can generate fake keyboard and mouse events on connected PCs, and the consequence of the faked input is windows switching activation normally.
So, my initial idea is for your usermode "Device" application to synthesize actual keyboard messages - SendInput seems a likely candidate for "the API that can "fake" real user input events.
Then, use an API like RegisterHotKey in your "UI" app to respond to the hotkey combination your device app generates.
Now, (assuming that SendInput IS generating user input events at the correct level), you should (from within the WM_HOTKEY handler in your UI app) have permission (because everything was "user initiated") to change the foreground window (to yourself).
Vista introduced the desktop composition feature. In short, all windows are drawing to a memory bitmaps and the Desktop Window Manager is then composing these bitmaps and drawing on a full-screen Direct3D surface. Full-screen windows do not participate in the desktop composition and get to draw directly on the screen (mostly because the majority of full-screen apps are games that need real-time screen updates).
In particular, this means that when a full screen app is up and running, it is covering the DWM composed image and the user needs to switch to a DWM-managed window for the DWM to start drawing on top of the full-screen app.
I don't have a good solution for your problem, unfortunately. One way to solve it would be to add the WS_CAPTION style to your app and then handle WM_NCPAINT/WM_NCCALCSIZE/WM_NCHITTEST yourself. This would allow you to lie to the DWM that you are a regular windowed application, but change visually your NC area to look like you have no title. However, this does require certain amount of additional code and might be a bit more effort you want to invest.
Another way you can try to solve your problem is to explicitly minimize your full-screen application window when launching the new process. However, you will then have to solve the problem of when to maximize it back again.
Btw, you might find the comments on this post from Raymond Chen interesting.
Windows supports multiple desktops and my guess would be that the full screen up is using a different desktop than the default one (where your application will be shown). A desktop object in Windows is "a logical display surface and contains user interface objects such as windows, menus, and hooks". For example, screen savers normally are started on a separate desktop.
You can find out which desktop an application is running on using Process Explorer:
Set Process Explorer to replace Task Manager and to run always on top.
When your full screen up is shown, launch Process Explorer by pressing Ctrl + Shift + Esc
Within Process Explorer, select the full screen process and press Ctrl + H to display the handles of this process
See the value of the Desktop item in the list. Usually this would be set to Default
If you know what desktop this app is running on you can start your process on the same desktop by first calling OpenDesktop to get a handle to this desktop and then pass it into the STARTUPINFO of your CreateProcess call.

How to reparent a Cocoa window?

I need to host my window upon a window of another application.
How to enumerate windows of another Cocoa application? Is it possible to control
them?
If no: how can I draw upon a window of another application?
Thanks!
How to enumerate windows of another Cocoa application?
You can enumerate the windows of another application using the Accessibility API. It doesn't matter whether that application is Cocoa or not.
Is it possible to control them?
Here, it does matter, indirectly, whether the application is Cocoa (or Carbon using standard controls). More precisely, it matters whether the application is accessible.
It usually is possible to move another window, resize it, or do simple things with controls in it (such as press buttons).
It is not possible to tape one of your windows to a window in another application. You will have to observe its location and move your window when the other moves. Following a live drag this way is not possible.
If no: how can I draw upon a window of another application?
You can't. You can only draw in your own windows.
You can make a transparent overlay window and draw on that, but that gets you back to the problem of taping one of your windows to a window in another application.
You should probably ask a broader question about whatever it is you hope to achieve by taping one of your windows to a window in another application or by drawing into a window in another application.
Checkout CGWindow.h
CGWindowListCreateDescriptionFromArray() is probably what you're looking for.
Cocoa does not support reparenting of another application window, or drawing on it.
But, there're two ways to get windows attributes for all the applications, like position, size, z-order, etc.
Accessibility API (also allows to control a foreign application window: move, resize, press buttons on it, etc.). If a foreign application does not support Accessibility API, then...
Quartz Window Services and a sample code for them, called "Son of Grab".

Resources