How to know which window has focus and how to change it? - x11

I would like to know how can I ask X11 which windows has the focus. And if for any reason my own application (that may be visible or not) got the focus I want be able to let the former windows get the focus again.
For instance, my application is running with many others (e.g. firefox, gvim, nautilus, ...)
Suppose that at first firefox has focus and that the user clicked on my app which now has the focus. I want that my application put the focus on firefox again.
Does anyone knows how to achieve this? Books recommendations would be very nice.

Take a look at the _NET_ACTIVE_WINDOW value of the root window which is set by most modern window managers:
xprop -root _NET_ACTIVE_WINDOW
This value can, of course, be obtained using Xlib library calls.

You probably want the XGetInputFocus call.
Window focused;
int revert_to;
XGetInputFocus(dpy, &focused, &revert_to);
In this snippet, focused will be the window with current input focus, getting keyboard events and mouse button presses.
This will work even if the window manager does not set the _NET_ACTIVE_WINDOW property on the root window, as specified by EWMH. A few window managers, such as dwm and my 9wm, don't set this.

I recommend an application called XDoTool. It supports quite a lot of queries, controls, and even hooks.
> xdotool getwindowfocus # 29360135
> xdotool getwindowfocus getwindowpid # 12988
> xdotool getwindowfocus getwindowname # tilda
> xdotool getwindowfocus behave '%#' blur getmouselocation
# or focus, mouse-enter, etc.
x:514 y:317 screen:0 window:56623121
x:271 y:26 screen:0 window:56623121
...
Commands like behave accept a callback, which can be built-in like getmouselocation or external like exec notify-send 'focused window', exec zsh myscript.zsh, etc., however you want to use it.
Edit - you can focus using xdotool windowfocus [options] [window], as in xdotool search --class firefox windowfocus. In my case this causes errors because Firefox shows up as a couple dozen 'windows', but all have the same PID; it works given the right ID. Hopefully that's a start.
Edit 2 - the 'window ID' is the decimal representation of the window pointer, e.g. from xprop:
> xprop -root _NET_ACTIVE_WINDOW
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x1c00007, 0x0
> xdotool getwindowfocus
29360135
> printf '%d\n' '0x1c00007'
29360135

Use this XQueryTree to find the currently active, or top-most window.
Here is a function, when given a display, it will find the current window in focus:
static Window
GetCurrWindow(d)
Display *d;
{
Window foo;
Window win;
int bar;
do{
(void) XQueryPointer(d, DefaultRootWindow(d), &foo, &win,
&bar, &bar, &bar, &bar, &bar);
} while(win <= 0);
#ifdef VROOT
{
int n;
Window *wins;
XWindowAttributes xwa;
(void) fputs("=xwa=", stdout);
/* do{ */
XQueryTree(d, win, &foo, &foo, &wins, &n);
/* } while(wins <= 0); */
bar=0;
while(--n >= 0) {
XGetWindowAttributes(d, wins[n], &xwa);
if( (xwa.width * xwa.height) > bar) {
win = wins[n];
bar = xwa.width * xwa.height;
}
n--;
}
XFree(wins);
}
#endif
return(win);
}
http://tronche.com/gui/x/xlib/window-information/XQueryTree.html
I found the source:
http://examples.oreilly.com/networksa/tools/xsnoop.c
Good Luck

Related

How to make Qt app visible on top on all screens?

How can I make a Qt window (keyboard launcher) show up on all spaces like e.g. Spotlight or iterm2 hotkey window.
I need to achieve the following: The launcher window has to be able to show up on every screen, even full screen apps, no dock item, not window switcher item, no main menu, this should work without any further implications (see below). Nice to have would be if the settings window would be still a regular window.
I tried to use qputenv("QT_MAC_DISABLE_FOREGROUND_APPLICATION_TRANSFORM", "1"); but using this the window accepts no keyboard input anymore. I also tried
WId windowObject = this->winId();
objc_object * nsviewObject = reinterpret_cast<objc_object *>(windowObject);
objc_object * nsWindowObject = ((objc_object* (*)(id, SEL))objc_msgSend)(nsviewObject, sel_registerName("window"));
int NSWindowCollectionBehaviorMoveToActiveSpace = 1 << 1;
int NSWindowCollectionBehaviorTransient = 1 << 3;
int NSWindowCollectionBehaviorFullScreenAuxiliary = 1 << 8;
int total = NSWindowCollectionBehaviorMoveToActiveSpace
|NSWindowCollectionBehaviorTransient
| NSWindowCollectionBehaviorFullScreenAuxiliary;
((objc_object* (*)(id, SEL, int))objc_msgSend)(nsWindowObject, sel_registerName("setCollectionBehavior:"), total);
but this way the window does not show over fullscreen apps and also has still a dock item and main menu.

Get the last ShowWindow state for a window in winapi

When you click a window in your taskbar (Windows users) it will retain it's last state - maximised or normal scalable window. I'm trying to do a similar thing, but programatically and without the window gaining focus (eg. becoming foreground and disturbing my current activity in another window).
Can I do that? Current window state can be obtained using this API call:
//Empty Window placement structure
WinDefExt.WINDOWPLACEMENT placement = new WinDefExt.WINDOWPLACEMENT();
//winapi call to external User32.dll file
UserExt.GetWindowPlacement(hwnd, placement);
//showCmd should be equal to one of the SW_ constants (here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548%28v=vs.85%29.aspx)
placement.showCmd;
ShowWindow isn't a "state", it's an "action". There's no GetShowState command. You can infer a value from the current state of the window, but there's no way to find out the actual last value used with ShowWindow.
if (!IsWindowVisible(hWnd))
swState = SW_HIDE;
else
if (IsIconic(hWnd))
swState = SW_MINIMIZE;
else
if (IsZoomed(hWnd))
swState = SW_MAXIMIZE;
else
{
// not hidden, minimized or zoomed, so we are a normal visible window
// last ShowWindow flag could have been SW_RESTORE, SW_SHOW, SW_SHOWNA, etc
// no way to tell
swState = SW_SHOW;
}

Showing a windows with XCB / Strange Behaviour

I'm trying to show a window in xcb, inside the main window, but actually without luck.
The idea is that when the user press a button (in that case the X button) a small white window is shown (just for test).
But actually i'm stuck on that step. I watched the example code here:
http://en.wikibooks.org/wiki/X_Window_Programming/XCB
And tried to do the same in my application.
[EDIT 28/10/2013] Now with that code i can show a window, but if i try to add other variable like int i=0, or whatever, the window doesn't appear, and no expose events were raised (all events that were raised are or 0 or 2 (even if i add the variables inside other events). Any idea?
This is the XCB_KEY_PRESS event handler code:
Edit (with the new code)
case XCB_KEY_PRESS:{
xcb_key_press_event_t *kp = (xcb_key_press_event_t *)ev;
if(kp->detail==53){
printf("X pressed\n");
uint32_t vals[2];
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
vals[0]=screen->white_pixel;
vals[1]=XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
win = xcb_generate_id(connection);
xcb_create_window(
connection,
XCB_COPY_FROM_PARENT,
win,
root,
80,80,
150,150,
10,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
mask, values);
mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
vals[0]=screen->white_pixel;
vals[1]=0;
background=xcb_generate_id(connection);
xcb_create_gc(connection, background, win, mask, vals);
xcb_map_window(connection,win);
xcb_flush(connection);
printf("finished\n");
}
printf("KEY_PRESS - Pressed: %d\n", kp->detail);
}
root is the root window obtained from xcb_screen_t variable.
The definition of background and win are the following:
xcb_window_t win;
xcb_gcontext_t background;
And i added even a XCB_EXPOSE event handler:
case XCB_EXPOSE:{
printf("EXPOSE NEW WINDOW CREATED\n");
xcb_poly_fill_rectangle(connection, win, background,1,&rectangle);
xcb_flush(connection);
}
What is wrong with that code? What am i missing? (I'm trying to develop a very basic window manager, just for fun)
(My idea for that program is that when x is pressed an input box is shown, do you have any suggestion on how to do that?)

How can I programmatically close the story editor in InDesign using ExtendScript?

I use a script which opens the story editor like this:
app.menuActions.itemByID(119793).invoke();
How can I close it programmatically? How can I detect whether it's opened or closed?
A story editor window may be closed with its close method.
Here is a function which closes the story editor window if it's open. It tests for the presence of a zoom property on the window to determine whether the window is a story editor or not (Thanks Loic Aigon for this idea)... There must be a better way of doing this but I haven't found it.
function closeStoryEditor() {
var windows = app.activeDocument.windows,
nbWindows = windows.length,
i,
closedWindow = false;
for (i = 0; !closedWindow && i < nbWindows; i += 1) {
if (!windows[i].hasOwnProperty("zoom")) {
// Let us presume that a window without a zoom method is a story editor window...
windows[i].close();
closedWindow = true;
}
}
}
To close it, it's…the same call ! if you want to check if the editor is already opened, you can loop through all open windows like this :
app.activeDocument.windows.everyItem().name;
and see for matches.
Loic
http://www.loicaigon.com

Testing to see if a window is maximized

I noticed that in Windows, if you maximize a window you can not resize it until you un-maximized it again. This appears to be a normal behaviour, so I would like to remove my resize gripper when the window is maximised.
At the moment I can't find a property to detect if a window is maximized, and although I could add a boolean in my controller, it wouldn't necessarily catch requests to maximize from the OS.
So if you know of a reliable way to test if a window is maximized please let me know.
On a related note, I am using custom chrome, and when I maximize a window it overlaps the windows task bar. I can think of hacks to detect available screen size (using a transparent system chrome window), but it would be good to know of a better method.
Thanks
Rob
In your application (MXML) on the in the init method you ussually call on creationComplete:
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="init()" >
Add the following code:
this.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGE, trackState);
the method looks like this:
public function trackState(event:NativeWindowDisplayStateEvent):void
{
if (event.afterDisplayState == NativeWindowDisplayState.MAXIMIZED)
{
isMaximised = true;
} else {
isMaximised = false;
}
}
I have figured out how this can best be done thanks to some pointers from TheBrain.
Firstly you need to watch for resize events to the window your want to control:
NativeApplication.nativeApplication.activeWindow.addEventListener(NativeWindowBoundsEvent.RESIZE, onWindowResize);
Then handle that event to decide if the window is maximised or not:
public function onWindowResize(event:NativeWindowBoundsEvent):void
{
if (event.afterBounds.height >= Screen.mainScreen.visibleBounds.height && event.afterBounds.width >= Screen.mainScreen.visibleBounds.width)
isMaximised = true;
else
isMaximised = false;
}
You then need to catch or create your own maximize button, and when clicked perform the following code:
if (isMaximised)
{
var bounds:Rectangle = Screen.mainScreen.visibleBounds;
NativeApplication.nativeApplication.activeWindow.bounds = bounds;
}
else
{
NativeApplication.nativeApplication.activeWindow.bounds = new Rectangle(100, 100, 500, 600);
}
You can modify the bounds to over maximize (which is handy for custom chrome windows with shadows), and you can also set the application to reset to a default size if the maximize button is clicked when it's already maximized (or do nothing).
I had issues about when to assign the window resize listner, and ended up removing and adding it every time the maximize button was clicked. It's a bit of overkill, but not too bad.
There is Win32 API Call that will do this for you:
BOOL IsZoomed( HWND hWnd );
to get the actual usable space from the screen, use the flash.display.Screen class, or you can use the systemMaxSize() which returns the largest window size allowed by the OS. For maximization you have some events that the window is dispaching when maximized/minimized/restored. You can find more info on the adobe pages (the link under systemMaxSize).
To detect if window is maximized...I don't think there is such a function (I might be wrong) but you can test if the app size is equal with the available screen size which means it's maximized. Or hook on the resize event which is triggered when the app is maximized/minimized/resized
Here is an easier way of checking if a window is maximized:
if(stage.nativeWindow.displayState == NativeWindowDisplayState.MAXIMIZED)
{
//do something
}
The following worked for me. No need to set event listeners, this code can be used to check the real-time state of the native window:
if (nativeWindow.displayState == 'maximized')
{
trace('Maximized');
}
else
{
trace('Minimized');
}
Can you use something like this to hook the maximize() event?

Resources