You are not logged in.
I want to change my Xmodmap slightly based on what window is focused. I'm using DWM if it matters. Bash would probably be best, but I don't really care if it's ruby, python, or perl...
I found this
A C utility to print the window ID of the currently focused window on stdout:
/* xgetfocus.c - link against libX11 */ #include <X11/Xlib.h> #include <stdio.h> int main(int argc, char *argv[]) { Display *display; Window focus; int revert; display = XOpenDisplay(NULL); XGetInputFocus(display, &focus, &revert); printf("%d\n", (unsigned)focus); return 0; }
here https://bbs.archlinux.org/post.php?tid=56646&qid=622489
but it doesn't compile for me
xgetfocus.c:(.text+0x15): undefined reference to `XOpenDisplay'
xgetfocus.c:(.text+0x30): undefined reference to `XGetInputFocus'
But I haven't compiled c in years and might not be doing it right...
Last edited by tladuke (2011-04-16 01:34:07)
Offline
Ah thanks. That compiles, but now I realize it outputs the window ID, not title. Why am I trying to write c? I will be here all night...
Last edited by tladuke (2011-04-16 01:49:47)
Offline
DWM isn't EWMH/NETWM-compliant, which, AFAIK, makes this not possible unless you were to patch DWM.
Last edited by Wintervenom (2011-04-16 01:57:08)
Offline
It doesn't take much to extend this to get a real titlebar name:
/* xgetfocus.c - link against libX11 */
#include <X11/Xlib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
Display *display;
Window focus;
char *window_name;
int revert;
display = XOpenDisplay(NULL);
XGetInputFocus(display, &focus, &revert);
XFetchName(display, focus, &window_name);
printf("%s\n", window_name);
return 0;
}
Offline
Thanks again. I think I have bigger probloms now. I need to make it a daemon listens for window focus change and does something when focus does change. I know something out there already exists, but I can't google it.
If DWM won't work, can someone suggest something else? I just need to bind a key to cycle through full screen windows. (and then modify my Xmodmap of course)
Offline
Thanks again. I think I have bigger probloms now. I need to make it a daemon listens for window focus change and does something when focus does change. I know something out there already exists, but I can't google it.
If you absolutely must have this, you're going to have to listen for X events. You'll need to look for an Xlib or XCB tutorial on the net that will show you how. (Prefer Xlib, it will be easier for a small script.)
The tricky part will be whether your window manager (presumably DWM) has any kind of support for EWMH hints. If it does, you're home free---you'll need to listen to PropertyNotify events on the root window and do something when the '_NET_ACTIVE_WINDOW' property is modified. If it doesn't, you're going to have to figure out how to properly interpret FocusIn and FocusOut events. See here and here. The focusing model is not intended for lesser mortals to comprehend.
I do not recommend this path unless you want to learn a bit of X programming. Please expend any and all efforts to find another means. Modifying your window manager may be easier. (An ideal solution would be if your window manager offered some sort of hook support.)
If you don't need precision, you could do the typical 'wait 5 seconds and probe the title of the currently active window' bit.
If DWM won't work, can someone suggest something else? I just need to bind a key to cycle through full screen windows. (and then modify my Xmodmap of course)
Ignoring the first half of this post, you should be able to get everything done with existing tools. Namely, wmctrl and xprop. *If* DWM supports EWMH.
For example, `wmctrl -l` will give a listing of all windows managed by the window manager. The first column will be the window ID and the fourth column will be the window title.
Then `xprop -root _NET_ACTIVE_WINDOW` will give you the window ID of the currently active window. (Use this to find the window in list generated by `wmctrl -l` to get the title of the currently active window.)
Alternatively, you could leave out wmctrl and use `xprop -id WINDOWID _NET_WM_NAME` and parse that output to get the title of the currently active window. (You still need to grab the active WINDOWID from the aforementioned 'xprop' command.)
If DWM doesn't support this very minimal level of EWMH (all you need is a way to get the ID of the currently active window, namely, _NET_ACTIVE_WINDOW), then this method will not work. If you must stick with DWM, you'll need to get your hands dirty with X or with DWM itself.
Education is favorable to liberty. Freedom can exist only in a society of knowledge. Without learning, men are incapable of knowing their rights, and where learning is confined to a few people, liberty can be neither equal nor universal.
Tu ne cede malis sed contra audentior ito
Offline
wmctl -l says
CAnnot get client list properties.
I tried in DWM and Openbox. Pretty sure openbox supports ewmh...
Offline
You tried `wmctrl -l` in Openbox and got 'Cannot get client list properties'? o_0 If so, could you post the output of `xprop -root` while using Openbox?
Last edited by BurntSushi (2011-04-17 16:36:22)
Education is favorable to liberty. Freedom can exist only in a society of knowledge. Without learning, men are incapable of knowing their rights, and where learning is confined to a few people, liberty can be neither equal nor universal.
Tu ne cede malis sed contra audentior ito
Offline
You tried `wmctrl -l` in Openbox and got 'Cannot get client list properties'? o_0 If so, could you post the output of `xprop -root` while using Openbox?
_XKB_RULES_NAMES(STRING) = "evdev", "evdev", "us", "", ""
XFree86_VT(INTEGER) = 7
Offline
Did something like what your looking for some time ago (I change the behavior of the mouse buttons instead).
You can get the windowid of the focused window with xdotool, feed that to xprop and dig out the title.
Here's a example that echo's the title (needs bash 4 to run)
#!/bin/bash
wnd_focus=$(xdotool getwindowfocus)
wnd_title=$(xprop -id $wnd_focus WM_NAME)
lookfor='"(.*)"'
if [[ "$wnd_title" =~ $lookfor ]]; then
wnd_title=${BASH_REMATCH[1]}
echo $wnd_title
fi
A tiling window manager simply manages your windows, not just letting you have em
:: Configs etc @GitHub
Offline
You can get the windowid of the focused window with xdotool, feed that to xprop and dig out the title.
Here's a example that echo's the title (needs bash 4 to run)
Nah, bash regex exists as far back as 3.2, but there's some small but odd differences in behavior during the ensuing dot releases. Your snippet (which is quite handy) runs just fine on my bash3 binary.
Offline
Am I missing some library or something? None of these types of commands work for me...
$ xdotool getwindowfocus
XGetInputFocus returned the focused window of 1. This is likely a bug in the X server.
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 20 (X_GetProperty)
Resource id in failed request: 0x1
Serial number of failed request: 19
Current serial number in output stream: 19
Offline
@tladuke - If that output from `xprop -root` is indeed while *Openbox* is running, then something is very seriously wrong. There should be a litany of atoms set.
Additionally, the error you get while running `xdotool getwindowfocus` is quite strange, and it doesn't rely on any EWMH adherence. Do you have anything special installed or weird that is running? Are you using a DE in addition to Openbox, or just plain Openbox? If the latter, what does your .xinitrc and/or ~/.config/openbox/autostart.sh look like?
Education is favorable to liberty. Freedom can exist only in a society of knowledge. Without learning, men are incapable of knowing their rights, and where learning is confined to a few people, liberty can be neither equal nor universal.
Tu ne cede malis sed contra audentior ito
Offline
.xinit is just:
/usr/bin/wminput -d -c boxee-buttons 00:19:1D:7C:C2:E1 &
exec openbox-session
edit:
openbox configs are from
$ cp /etc/xdg/openbox/{rc.xml,menu.xml,autostart.sh} ~/.config/openbox
and then I added "urxvt" to the bottom of autostart.
I do get a working urxvt, but none of the openbox keyboard commands that i just looked up seem to work....
Last edited by tladuke (2011-04-18 04:32:22)
Offline
greyscale wrote:You can get the windowid of the focused window with xdotool, feed that to xprop and dig out the title.
Here's a example that echo's the title (needs bash 4 to run)Nah, bash regex exists as far back as 3.2, but there's some small but odd differences in behavior during the ensuing dot releases. Your snippet (which is quite handy) runs just fine on my bash3 binary.
Thx, good to know.
Always used the more old-school way with sed etc until recent and read some writing on the net warn about it needing bash 4.
But might not have been the regexp they meant either since that article covered a couple of different topics on bash.
A tiling window manager simply manages your windows, not just letting you have em
:: Configs etc @GitHub
Offline
.xinit is just:
/usr/bin/wminput -d -c boxee-buttons 00:19:1D:7C:C2:E1 &
exec openbox-sessionedit:
openbox configs are from
$ cp /etc/xdg/openbox/{rc.xml,menu.xml,autostart.sh} ~/.config/openboxand then I added "urxvt" to the bottom of autostart.
I do get a working urxvt, but none of the openbox keyboard commands that i just looked up seem to work....
Could you please make sure that Openbox is *running*.
(Did you put a '&' after calling 'urxvt' in autostart.sh?)
Education is favorable to liberty. Freedom can exist only in a society of knowledge. Without learning, men are incapable of knowing their rights, and where learning is confined to a few people, liberty can be neither equal nor universal.
Tu ne cede malis sed contra audentior ito
Offline
[
(Did you put a '&' after calling 'urxvt' in autostart.sh?)
doh
that fixes it
thanks, guys. getting closer...
Offline
Using only xprop:
xprop -id $(xprop -root _NET_ACTIVE_WINDOW | cut -d ' ' -f 5) _NET_WM_NAME
Using xdotool:
xdotool getactivewindow getwindowname
You can also use xdotool to run commands on changes in focus:
xdotool search . behave %@ focus getwindowname
You can then either use the `exec` xdotool command to run external commands, or pipe the above into a `while read` loop. Note however that if you wish to do the latter there is a problem with the printf buffers in the current version (2.20101012.3049), but it is fixed in VCS.
Enjoy.
Offline
Old thread, but doesn't look outdated.
How should that C code be edited in order to retrieve currently active window class?
xprop is not an option since I'm running DWM.
I managed to patch this piece of code, but it fetches only the terminal window class; if any other window is made active, 'Segmentation fault' gets printed to stdout instead:
/* xgetfocus.c - link against libX11 */
#include <X11/Xlib.h>
#include <stdio.h>
#include <X11/Xutil.h>
void win_class(Display* d, Window w){
Status s;
XClassHint* class;
class = XAllocClassHint();
s = XGetClassHint(d, w, class);
printf("%s\n", class->res_class);
}
int main(int argc, char *argv[]) {
Display *d;
Window w;
char *window_name;
int revert;
d= XOpenDisplay(NULL);
XGetInputFocus(d, &w, &revert);
XFetchName(d, w, &window_name);
printf("%s\n", window_name);
win_class(d, w);
return 0;
}
EDIT: (why I'm even after this)
Window class is needed for a bash script which translates inputs depending on the window. For instance, if the window belongs to 'Chromium' class, then Altkey + Button6 would trigger
xdotool key --clearmodifiers alt+Left
in order to move back in history. Some other classes require different input and so on.
Last edited by azb (2013-04-06 14:19:16)
Offline
Why is xprop not an option? That is not dependent on anything special in the windowmanager.
My window manager is *far* less compliant with any of those standards than dwm is, and xprop works just fine.
But if you want to do it in C, check the xlib documentation for XGetWindowProperty. I don't understand any of the talk in this thread about window managers: if you are using xlib to query the x server directly, the window manager is completely irrelevant - you don't even need to have a window manager running.
The WM is only relevant if you are using tools like xdotool.
Last edited by Trilby (2013-04-06 14:35:54)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Online
I'm simply assuming the WM is what makes the difference, since under compiz for instance my scripts work.
xprop -id $(xprop -root -f _NET_ACTIVE_WINDOW 0x " \$0\\n" _NET_ACTIVE_WINDOW | awk "{print \$2}") | awk '/WM_CLASS/{print $4}'
works for class retrieval under compiz, but returns "xprop: error: Invalid window id format: not." in DWM
Also, if I were to fetch class by win ID
xprop -id WINID
then it works only for terminal window as well. Returns nothing for other windows' IDs.
Last edited by azb (2013-04-06 14:58:41)
Offline
Ah, you're trying to get atoms only set by some WMs. Xprop will work fine, but it can only get the information that is there. I forgot that I don't think xprop by itself has a way to get the focus window.
For the C code, XGetWindowProperty will work, but the error from any "non-terminal" windows is that there are child windows. You need to use XQueryTree in a loop to "drill down" to the deepest child window.
Here is an example from one of my projects to get the window the mouse is currently over - you'll need to revise to change XQueryPointer to XQueryTree:
XQueryPointer(dpy,root,&ev.xbutton.root,&ev.xbutton.window,&ev.xbutton.x_root,&ev.xbutton.y_root,&ev.xbutton.x,&ev.xbutton.y,&ev.xbutton.state);
ev.xbutton.subwindow = ev.xbutton.window;
while(ev.xbutton.subwindow) {
ev.xbutton.window = ev.xbutton.subwindow;
XQueryPointer(dpy,ev.xbutton.window,&ev.xbutton.root,&ev.xbutton.subwindow,&ev.xbutton.x_root,&ev.xbutton.y_root,&ev.xbutton.x,&ev.xbutton.y,&ev.xbutton.state);
}
EDIT: this may not actually be needed - your code works fine here as is.
Last edited by Trilby (2013-04-06 15:25:06)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Online
Ah, you're trying to get atoms only set by some WMs. Xprop will work fine, but it can only get the information that is there. I forgot that I don't think xprop by itself has a way to get the focus window.
For the C code, XGetWindowProperty will work, but the error from any "non-terminal" windows is that there are child windows. You need to use XQueryTree in a loop to "drill down" to the deepest child window.
Here is an example from one of my projects to get the window the mouse is currently over - you'll need to revise to change XQueryPointer to XQueryTree:
XQueryPointer(dpy,root,&ev.xbutton.root,&ev.xbutton.window,&ev.xbutton.x_root,&ev.xbutton.y_root,&ev.xbutton.x,&ev.xbutton.y,&ev.xbutton.state); ev.xbutton.subwindow = ev.xbutton.window; while(ev.xbutton.subwindow) { ev.xbutton.window = ev.xbutton.subwindow; XQueryPointer(dpy,ev.xbutton.window,&ev.xbutton.root,&ev.xbutton.subwindow,&ev.xbutton.x_root,&ev.xbutton.y_root,&ev.xbutton.x,&ev.xbutton.y,&ev.xbutton.state); }
EDIT: this may not actually be needed - your code works fine here as is.
Okay, then it explains the erroneous behavior.
Works for you? Interesting. If anyone using DWM as well could confirm this, that would be nice.
Offline
The C code definitely has absolutely nothing to do with the window manager.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Online