How do I find the name of the running X window window manager from a program?
If I start another window manager when one is already running, then an error occurs, so there must be a way for the other window manager to detect the first one.
How does it work?
By the EWMH spec, a compliant window manager will set the _NET_SUPPORTING_WM_CHECK property on the root window to a window ID.
If the _NET_SUPPORTING_WM_CHECK property exists and contains the ID of an existing window, then a ICCCM2.0-compliant window manager is running. If the property exists but does not contain the ID of an existing window, then a ICCCM2.0-compliant window manager exited without proper cleanup. If the property does not exist, then no ICCCM2.0-compliant window manager is running.
That window (not the root window, but the one described by a property on the root window) should have a _NET_WM_NAME property on it, which is what you are looking for.
The wmctrl command can display information about many EWMH/NetWM-compatible X window managers including their names:
$ wmctrl -m
Name: Compiz
...
Accroding to its Wikipedia page, it works with the following window managers at the present moment (Aug 2012):
blackbox >= 0.70
icewm
kwin (the default WM for KDE)
metacity (the default WM for GNOME)
openbox >= 3 (the default WM for Lubuntu)
sawfish
fvwm >= 2.5
waimea
pekwm
enlightenment >= 0.16.6
xfce >= 4
fluxbox >= 0.9.6
matchbox
window maker >= 0.91
compiz
awesome
wmfs
You may find an "atom" that has the information, but I don't think there is a 100% guarantee that all window managers use the same atom. Do an "xlsatoms" to list the atoms on your server, or "xprop" (and click) to see the properties (including atoms and their values) of a particular window.
Related
Does X have the notion of non-clipped child windows? The behavior in
Windows and OSX for these is:
the parent always stays behind its children
the children are closed automatically when the parent is closed
the children follow the parent when moving
If the answer is no, then I can emulate 2 and 3 but how about 1?
Thanks,
Cosmin.
The closest thing to overlapped non-clipped child windows in X is the window property WM_TRANSIENT_FOR. This will create a window that:
will not appear on the taskbar
will not have minimize and maximize buttons
will be minimized along with its transient-for window
will always stay on top of its transient-for window (most important)
Yes ( you can override this if you implement your own composite manager )
Yes, unless window is added to a "save set".
Yes ( but again with your own composite manager you can change visual mapping of [content of all windows hierarchy] -> [screen] any way you want )
I'm looking to hide a window on OSX (not belonging to my app), but not the rest of the application. I have tried simply moving the window off the screen (like I would do in Windows), but the api always positions it at least 20 pixels away from the edge (#annoying).
Other things I have thought of:
Setting the opacity of the window to zero (can this be done?)
Minimizing the window, but it appears that the window handle becomes null once the window is minimized, so might be hard to get back
Setting the window level (i.e. desktop) or z order (can this be done?)
Moving the window to a different workspace (can this be done?)
Does anyone know of a way to do this?
I have an app which creates a series of modeless dialog windows which are shown in a 'cascade. The user is supposed to be able to click on any window to bring it to the top and interact with it.
Here's a screenshot, showing this working as intended. The user has clicked on the window 3rd from the bottom, successfully bringing it to the top.
A user reports that when he runs this, and clicks on one of the obscured window then the window does not rise to the top.
Here is a video showing the problem occurring. It shows a normal cascade of notebook windows, behaving as expected. Then a cascade of my application windows appears, but the user cannot bring any selected window to the top. The selected window changes appearance, indicating that it has been selected, but it remains obscured. ( The video concludes by demonstrating a related problem, which we can probably ignore for now )
The user reports that this problem occurs on other PCs he has tried. I cannot reproduce the problem.
I am completely stumped and cannot even guess what might be causing this.
( One theory I had was that the app had frozen and was no longer responding to paint messages. However, the video shows the user dragging the obscured window out of the cascade, and then the window is painted just fine. It seems clear that the app does not get a paint message, or ignores it, when the window is selected )
The app is written using C++ and wxWidgets 2.9.4 and runs under windows 7
This appears to be a wxWidgets 2.9 issue. When built with v2.8.12 libraries, the user reports that it works fine.
Here is the code to create the windows. Note that the parent is NULL. ( This allows the main application window to be minimized without minimizing the cascade windows - a required feature. )
cNewDataPopup::cNewDataPopup( cPatDataset& data )
: wxDialog(NULL,-1,L"New data",wxPoint(200,200),wxSize(570,242),
wxDEFAULT_DIALOG_STYLE|wxSTAY_ON_TOP )
, myData( data )
{
After some experimentation, I found that adding wxDIALOG_NO_PARENT to the wxSTAY_ON_TOP 'fixes' the problem.
( The following explanation is due to VZ. )
Apparently, specifying the window's parent as NULL is not sufficient to convince wxWidgets that you want no parent. It goes ahead and assigns a parent anyway, more or less at random. This is why odd, unexpected and unreproducible behaviour is observed. The algorithm for assigning a parent was changed in v2.9.x, which is why the odd and unexpected behaviour changes when I upgraded wxWidgets. In order to convince wxWidgets that, yes, really, I do not want a parent for a window, I have to specify BOTH a NULL parent and the wxDIALOG_NO_PARENT style.
The use of wxSTAY_ON_TOP is almost certainly the culprit. If you just need the windows to stay on top of the parent window, don't use this style, either use wxFRAME_TOOL_WINDOW or override WM_SIZE handling by overriding MSWWindowProc() in your parent frame.
I develop a program on mac OS X using Qt 4.8 as the title.
Now I'm facing a problem that I spent a lot of time on it but still cannot solve.
I have a QWidget (called A) which will open a QMainWindow (called B) after some operation.
When B is opened, I need A to be blocked by B, so I set A as B's parent and set the window modality of B to Qt::WindowModal.
On other platform, it works as what I thought, however, when it comes to mac, B doesn't have its own title bar, it just popped up and attached to the title bar of A. And also, the close button on the title bar of A is grey-out, which means I cannot close B by the button, I need to use an exit QAction on QMenu to close it.
When I set B's parent to 0(NULL) instead of B, then it has independent title bar just as on windows or linux, that's what I want. However it lost the property that B blocked by A.
I tried to set the windows flags such as Qt::CustomizeWindowHint and so on, but no one works.
Is there any way to keep the hierarchal relationship between A and B, and gives B an independent title bar on Mac? Thanks for everyone's help :)
ps. I tried on small program and found that this situation only happened on WindowModal (NonModal and ApplicationModal works fine)
The behavior you are describing is known as sheets on Mac OS X. As you suspected, there is a value for the window flags enum that specifies if the window is to be a sheet. Based on the documentation, it appears that calling setWindowModality() on OS X may default the window to being a sheet -- which is probably what most developers would want for most dialogs. You might try testing for and explicitly removing that flag after setting the modality and see if that helps. Alternately, you may want to check which flags are set, and see if that leads to a solution.
I want to set a certain window, from an external app (for example textedit), to be front most.
I can successfully get a reference to the app itself using GetFrontProcess, and check whether it is front most. If it is not, I can use setFrontProcess to make it focussed.
I can then use the the accessibility API to examine all the windows under that application. I am checking that a certain window exists, and if so I compare it against the front most window of the application:
//get the front window of textEditApp and store it in 'currentFrontWindow'
AXUIElementCopyAttributeValue(textEditApp, kAXFocusedWindowAttribute, (CFTypeRef *)¤tFrontWindow);
If the window I am interested in is not frontmost, I need to set it so. I thought that I could use AXUIElement Set AttributeValue to do this but I am not getting any success. Below is how I have tried to do it.
//set the front window of textEditApp to be desiredFrontWindow
AXUIElementSetAttributeValue(textEditApp, kAXFocusedUIElementAttribute, desiredFrontWindow);
I have checked that the window exists, and the application is 'switched to' successfully. But why doesn't this line of code bring the specified window to the front?
Thanks.
But why doesn't this line of code bring the specified window to the front?
Because you tried to set a read-only attribute.
In order to make a window frontmost, you need to set the appropriate property of the window. The same goes for an application: To make an application frontmost, you need to set the appropriate property of the application.
The Cocoa/Mac OS X name for the frontmost window is “the main window”. (See, for example, NSApplication's and NSWindow's methods relating to that concept.) Accessibility uses the same name, so to make a single window frontmost, set the value of its kAXMainAttribute to kCFBooleanTrue.
The way to make the application frontmost is similar: Set the value of its kAXFrontmostAttribute to kCFBooleanTrue. You'll need to do both of these to both set the frontmost window of the application and make the application active.
As far as I can tell, there is no way to bring only a single window of an application frontmost and give it session focus.
I was able to accomplish this in an app I worked on by bringing the application to the front, then bringing a single window to the front.
First bringing the app to the front:
let currentPid = NSRunningApplication.currentApplication().processIdentifier
if let pid = (the pid of the app in question) where pid != currentPid {
NSRunningApplication(processIdentifier: pid)?.activateWithOptions(.ActivateIgnoringOtherApps)
}
Then sending the window to the front:
let window = (window AXUIElement)
AXUIElementSetAttributeValue(window, NSAccessibilityMainAttribute, true)
I recently discovered that, if you don't mind some Carbon, you can use SetFrontProcessWithOptions to bring a window to the front and give it focus if you pass kSetFrontProcessFrontWindowOnly as the second argument.