Look at the screen capture below - note how Windows groups taskbar icons of the same kind (VirtualBox + virtual machine on the left and two Explorer windows on the right). How would you go about doing this for your own application? Are the icons automatically grouped by process, or can you force Windows to group different processes too?
I've been Googling for this but I'm not quite sure what it is called. All links I've found so far only talk about Windows settings which group / stack / group when full etc.
After a quick Google search, this is what popped up:
Application User Model IDs (AppUserModelIDs) are used extensively by
the taskbar in Windows 7 and later systems to associate processes,
files, and windows with a particular application. In some cases, it is
sufficient to rely on the internal AppUserModelID assigned to a
process by the system. However, an application that owns multiple
processes or an application that is running in a host process might
need to explicitly identify itself so that it can group its otherwise
disparate windows under a single taskbar button and control the
contents of that application's Jump List.
Read more about the topic on msdn.
Related
I'm using the XFCE4 desktop environment under Ubuntu 20.0.4.
I have several virtual desktops set up, each of which containing one or more applications which are running.
Is there any way I can run an X-Windows-based command from one desktop and have it manipulate a window in a different desktop, without switching desktops?
For example, suppose I have an xterm shell window running in virtual desktop 0, and that I currently am focused in virtual desktop 0.
And suppose I have a text editor window open in virtual desktop 1.
Is there any way for me to remain focused in desktop 0 and to run a command within the xterm shell window which will send text to the text editor window in desktop 1?
I don't want to see desktops shifting back and forth between desktop 0 and desktop 1 while this text is being sent to the text editor. I want to remain focused in desktop 0 for the entire duration of the running of this command.
I know I can use xdotool to send text to another X window, but xdotool only seems to function when the destination window is in the same virtual desktop which currently has the focus. For example, I can do the following with xdotool, but it won't work unless the destination window (referred to by $windowid in the following example) is in my currently viewed virtual desktop:
xdotool type --window $windowid Sample text
What I want is to send text and mouse clicks to windows in desktops that differ from the desktop that I'm currently viewing, and have the windows in those other desktops receive and respond to the text and mouse clicks without any switch to the other desktops taking place.
If necessary, I'm willing to write a program in C, C++, or pretty much any other language in order to implement this functionality.
But I'm wondering: is what I'm trying to do even possible in an X Windows environment?
Thank you very much in advance for any thoughts and suggestions.
Virtual Desktops:
Most X servers have only a single screen. The window manager may virtualize this resource and offer multiple so-called 'virtual desktops', of which only one can be shown on the screen at a time. There is some variation among the features of virtual desktop implementations. There may be a fixed number of desktops, or new ones may be created dynamically. The size of the desktops may be fixed or variable.
Implementation note
There are at least two options for implementing virtual desktops. The first is to use multiple virtual roots and change the current desktop by manipulating the stacking order of the virtual roots.
The second option is to keep all managed windows as children of the root window and unmap the frames of those which are not on the current desktop.
In any case, you should study the Extended Window Manager Hints.
These properties might be of interest to you:
Root Window Properties:
_NET_SUPPORTED - set by the Window Manager to indicate which hints it supports
_NET_CLIENT_LIST - all X Windows managed by the Window Manager
_NET_NUMBER_OF_DESKTOPS - indicate the number of virtual desktops
_NET_CURRENT_DESKTOP - the index of the current desktop
_NET_DESKTOP_NAMES - the names of all virtual desktops
_NET_VIRTUAL_ROOTS - a list of IDs for windows that are acting as virtual root windows
Application Window Properties:
_NET_WM_DESKTOP - determine the desktop the window is in (or wants to be)
_NET_WM_STATE - list of hints describing the window state
_NET_WM_ALLOWED_ACTIONS - list of atoms indicating user operations that the Window Manager supports for this window
Xlib:
Sending Events to Other Applications (XSendEvent)
Obtaining Window Properties (XGetWindowProperty)
Properties and Atoms (XInternAtom)
Obtaining Window Information (XQueryTree)
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."
I want to make a new group for windows in Windows XP taskbar. I would like to move windows from one group to another, how can I do this?
Here is image of one group which has 7 windows:
What I want to do is move out some windows into its own group.
What you are asking for is not officially supported in XP. The grouping is controlled by the OS based on the executable of each running process. Multiple instances of the same executable are grouped together. There is no option to change that behavior, only to enable/disable it in the Control Panel settings. If you want to manipulate groups, you have to do so manually using the Toolbar API and undocumented data structures, as outlined in this article: Manipulating Taskbar Buttons (use at your own risk).
The feature you are looking for is officially supported in Windows 7 and later by using Application User Model IDs instead. Windows that are assigned the same AppUserModelID are grouped together. Use SetCurrentProcessExplicitAppUserModelID() to set a process-wide AppUserModelID. If an app (like a legacy app) does not assign a process-wide AppUserModelID, the OS auto-generates one. The process AppUserModelID is used as the default when creating windows. A window-specific AppUserModelID can then be assigned using SHGetPropertyStoreForWindow() and IPropertyStore::SetValue() if needed. This allows a single process to have multiple taskbar groups, and multiple related processes to use a single shared taskbar group.
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...
I have been working on windows automation and monitoring.
What exactly happens when I lock the screen of a windows machine?
I am working with Windows 7 at the moment, are there big differences to the behavior if I switch to Vista or the server versions?
Is there still a desktop that can be accessed via api's?
I know that i can still send key strokes and mouse clicks to specific windows (via ControlSend and ControlClick), but there seems to be no "desktop" itself.
Could someone shed some light on this whole thing or point me at a readable source where I could get an overview over the topic?
Basically what happens is that Windows switches to the secure desktop, makes it the current one, so input is now associated with it.
The old desktop remains where it was: all the HWNDs on the desktop are still there, and any thread attached to that desktop can still access those HWNDs, get their location, and so on. You can still send messages to windows on this desktop, so long as the thread sending the message is also on that desktop.
However, since the desktop is now inactive, it cannot receive input. GetForegroundWindow will return NULL (IIRC), and you can't use SendInput any longer, since input now belongs to [a thread on] a different desktop; no controls on that inactive desktop can receive focus.
Note that sending keypress messages to a control that doesn't have focus can sometimes cause unexpected behavior, since the app or control generally never expects to receive keyboard input without getting the focus first. (This can be problematic for controls that set up some sort of input context in WM_SETFOCUS and clear it up in WM_KILLFOCUS, for example.)
In short, the UI is still there: you can do certain queries against it, but you can no longer automate it as you could on a regular desktop by sending input, and some other functions that relate to focus or input may fail.
I'm not super familiar with AutoHotKey, but the name and description of functionality suggests that it's heavily reliant on the underlying Win32 SendInput API. This won't work at all for keyboard input when a desktop is inactive.
For a reasonable overview of how desktops work and how they relate to winstations, the locked desktop, and so on, check out the Desktop article on MSDN.
One issue that I've run into in the past with desktops and automation is: how to I leave a long-running test that's using some form of user input automation (mouse, keyboard simulation), but still lock my PC so that someone can't just walk by and interfere with it. Once you lock the PC, the desktop is inactive, and so the automation stops working. A similar issue happens if the screensaver kicks in: the desktop switches, and the automation fails.
One solution is to use two PCs: let's call them Main and Test: from Main, open a remote terminal services client onto the Test machine, and then run the automated test on the test machine, but from a terminal services client window on the Main machine. Now the cool part: you can minimize that TSC window, or even lock the Main machine (or let the screensaver kick in), and that virtual session will continue working, thinking that it is still active - it's just that nobody is paying it any attention. This is one way to create a "connected" session with an active desktop, but one that no-one can interfere with, because it's protected behind the locked desktop of the Main machine.
I don't know the details, but I believe the lock screen constitutes a separate "desktop" and maybe also a separate "window station" (as I understand it a window station is merely a container for desktops). The MSDN section on window stations should hopefully be useful: http://msdn.microsoft.com/en-us/library/windows/desktop/ms687098%28v=vs.85%29.aspx
In order to access a desktop, you will need to use the regular windows api's from a thread that is on that desktop. SetThreadDesktop would probably be the easiest way to do that in C, as long as the desktop isn't on a different window station.
Unfortunately, this is already difficult for a regular privileged application, and using AutoHotkey complicates it even more. Since you don't have control over threads or over process initialization, you will probably have to create a new process in the other desktop (you can do this using the CreateProcess API, which appears to have a wrapper available for AHK to which you can supply a desktop name: http://www.autohotkey.com/forum/topic1952.html). Your process will need special privileges to do this; I'm not sure that even running as Administrator is enough.