Closed specialblend closed 7 years ago
not sure why ev.window is not defined. Can you log what's in ev
prop is not defined because of incorrect window param to X.GetProperty
. Try to use display.screen[0].root
instead of ev.window
@sidorares Thanks for the prompt response.
Here's the new code:
var x11 = require('x11');
x11.createClient(function (err, display) {
var X = display.client;
X.ChangeWindowAttributes(display.screen[0].root, {eventMask: x11.eventMask.PropertyChange});
X.on('event', function (ev) {
console.log(ev);
if (ev.name === 'PropertyNotify') {
X.GetAtomName(ev.atom, function (err, name) {
if (name === '_NET_ACTIVE_WINDOW') {
X.GetProperty(0, display.screen[0].root, ev.atom, X.atoms.WINDOW, 0, 4, function (err, prop) {
console.log(prop);
});
X.GetProperty(0, display.screen[0].root, ev.atom, X.atoms.WM_CLASS, 0, 4, function (err, prop) {
console.log(prop);
});
X.GetProperty(0, display.screen[0].root, ev.atom, X.atoms.WM_NAME, 0, 4, function (err, prop) {
console.log(prop);
});
}
});
}
});
});
Here's the full output from switching windows twice:
{ type: 28,
seq: 3,
name: 'PropertyNotify',
wid: 480,
atom: 402,
time: 47337714,
state: 0,
rawData: <Buffer 1c 00 03 00 e0 01 00 00 92 01 00 00 f2 50 d2 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> }
{ type: 28,
seq: 3,
name: 'PropertyNotify',
wid: 480,
atom: 317,
time: 47337715,
state: 0,
rawData: <Buffer 1c 00 03 00 e0 01 00 00 3d 01 00 00 f3 50 d2 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> }
{ type: 33, bytesAfter: 0, data: <Buffer 01 00 c0 03> }
{ type: 33, bytesAfter: 1, data: <Buffer > }
{ type: 33, bytesAfter: 1, data: <Buffer > }
{ type: 28,
seq: 8,
name: 'PropertyNotify',
wid: 480,
atom: 402,
time: 47342186,
state: 0,
rawData: <Buffer 1c 00 08 00 e0 01 00 00 92 01 00 00 6a 62 d2 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> }
{ type: 28,
seq: 8,
name: 'PropertyNotify',
wid: 480,
atom: 317,
time: 47342187,
state: 0,
rawData: <Buffer 1c 00 08 00 e0 01 00 00 3d 01 00 00 6b 62 d2 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00> }
{ type: 33, bytesAfter: 0, data: <Buffer fe 00 40 03> }
{ type: 33, bytesAfter: 1, data: <Buffer > }
{ type: 33, bytesAfter: 1, data: <Buffer > }
As you can see, I'm not longer getting errors, but I still can't get WM_NAME
or WM_CLASS
. I can confirm the windows are healthy and have the proper name:
cj@lighthouse:~/workspace/moodring$ xdotool getwindowfocus getwindowname
moodring - [~/workspace/moodring] - .../main.js - WebStorm 2017.1.4
Please advise on how to get the window properties such as name and class.
And finally, thanks so much for sharing this library!
you need to use ev.wid
instead of ev.window
try to have a look at https://github.com/santigimeno/node-ewmh ( as a library or as example )
also if you find yourself fixing bug in node-x11 examples or docs feel free to send pr so that everyone will benefit
I'll try your GetProperty
code later today, on a windows machine atm
@sidorares ev.wid
returns the same value as display.screen[0].root
, precisely 480
, so I'm getting the same results.
I'm more than happy to continuously contribute to this library (I need node.js practice) if you can accommodate getting me started.
Edit: I tried node-ewmh with no luck. The repository seems to be 3 years old at best and only support setting and not getting properties:
var x11 = require('x11');
var EWMH = require('ewmh');
x11.createClient(function (err, display) {
if (err) {
throw err;
}
var ewmh = new EWMH(display.client, display.screen[0].root);
ewmh.on('ActiveWindow', function (d) {
console.log(d);
});
ewmh.set
});
Output
events.js:160
throw er; // Unhandled 'error' event
^
Error: Could not set SubstructureRedirect to root window event_mask
at /home/cj/workspace/moodring/node_modules/ewmh/lib/ewmh.js:19:29
at ReadFixedRequest.callback (/home/cj/workspace/moodring/node_modules/x11/lib/xcore.js:490:39)
at ReadFixedRequest.execute (/home/cj/workspace/moodring/node_modules/x11/lib/unpackstream.js:41:10)
at UnpackStream.resume (/home/cj/workspace/moodring/node_modules/x11/lib/unpackstream.js:165:30)
at UnpackStream.write (/home/cj/workspace/moodring/node_modules/x11/lib/unpackstream.js:102:10)
at Socket.<anonymous> (/home/cj/workspace/moodring/node_modules/x11/lib/xcore.js:88:21)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at readableAddChunk (_stream_readable.js:176:18)
at Socket.Readable.push (_stream_readable.js:134:10)
happy to guide you @linkintosh don't hesitate to ask any question
Edit: I tried node-ewmh with no luck. The repository seems to be 3 years old at best and only support setting and not getting properties:
The problem is that ewmh
is supposed to be used to implement a window-manager. It you try to run it as a X11 client it won't work (setting SubstructureRedirect to the root window when other window manager is running is not allowed)
@santigimeno I thoughts It's for both sides ( WM reporting to clients and clients listening WM events ) Would be nice to add
@sidorares I agree, I just implemented WM side as was my use case at the time :).
Back to the OP issue. @SpecialBlend, it's normal the wid you get is the root
as the PropertyNotify
the event comes from the root
window. To get the active window wid
you need to get the _NET_ACTIVE_WINDOW
property and then use that wid to get WM_CLASS, WM_NAME, etc. As an example, something like this would work: (I'm using https://github.com/santigimeno/node-x11-prop, that is just a fancy wrapper over GetProperty()
):
var x11 = require('x11');
var x11prop = require('x11-prop');
var get_property = x11prop.get_property;
x11.createClient(function (err, display) {
var X = display.client;
X.ChangeWindowAttributes(display.screen[0].root, {eventMask: x11.eventMask.PropertyChange});
X.on('event', function (ev) {
console.log(ev);
if (ev.name === 'PropertyNotify') {
X.GetAtomName(ev.atom, function (err, name) {
if (name === '_NET_ACTIVE_WINDOW') {
// get active window
get_property(X, ev.wid, '_NET_ACTIVE_WINDOW', 'WINDOW', function(err, wid) {
if (!err) {
console.log('_NET_ACTIVE_WINDOW: ' + wid);
}
if (wid) {
get_property(X, wid, 'WM_CLASS', 'STRING', function(err, data) {
if (!err) {
console.log('WM_CLASS: ' + data);
}
});
}
});
}
});
}
});
});
@santigimeno that works perfectly, thank you so much! and thank you @sidorares for your help as well.
I'm quite new to node.js but I will be using both libraries (node-x11 and x11-prop) extensively and I'm happy to contribute to both as I learn more. Regards
I'm using this code snippet based on your post here
main.js
However, it seems that
ev.window
is null, as well asprop
:What's the proper way to listen for changes in the active (focused) window? I'm running Ubuntu 16.04 with Unity.