├── .gitignore ├── README.md ├── configs.json ├── index.js ├── package.json └── scripts ├── linux.sh ├── mac.scpt ├── mac.sh └── windows.ps1 /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Attention, this library is not maintained anymore!!! 2 | 3 | # active-window 4 | > Get active window title in Node.js. 5 | 6 | Compatible with Linux, Windows 7+, and OSX; 7 | 8 | ## Usage 9 | 10 | ```javascript 11 | var monitor = require('active-window'); 12 | 13 | callback = function(window){ 14 | try { 15 | console.log("App: " + window.app); 16 | console.log("Title: " + window.title); 17 | }catch(err) { 18 | console.log(err); 19 | } 20 | } 21 | /*Watch the active window 22 | @callback 23 | @number of requests; infinity = -1 24 | @interval between requests 25 | */ 26 | //monitor.getActiveWindow(callback,-1,1); 27 | 28 | //Get the current active window 29 | monitor.getActiveWindow(callback); 30 | 31 | 32 | ``` 33 | ## Tested on 34 | - Windows 35 | - Windows 10 36 | - Windows 7 37 | - Linux 38 | - Raspbian [lxdm] 39 | - Debian 8 [cinnamon] 40 | - OSX 41 | - Yosemite 10.10.1 42 | 43 | ## TODO 44 | 45 | - Test on more operating systems. 46 | - Use native APIs. 47 | 48 | ## License 49 | 50 | MIT 51 | -------------------------------------------------------------------------------- /configs.json: -------------------------------------------------------------------------------- 1 | { 2 | "linux": { 3 | "bin" :"sh", 4 | "parameters" : [], 5 | "script_url" : "scripts/linux.sh" 6 | }, 7 | "mac" :{ 8 | "bin" : "sh", 9 | "parameters" : [], 10 | "script_url" : "scripts/mac.sh", 11 | "subscript_url":"scripts/mac.scpt" 12 | }, 13 | "win32":{ 14 | "bin" :"powershell", 15 | "parameters" : ["-ExecutionPolicy", "Bypass","-File"], 16 | "script_url" : "scripts\\windows.ps1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var config = getConfig(); 3 | 4 | /** 5 | * This callback handle the response request by getActiveWindow function 6 | * @callback getActiveWindowCallback 7 | * @param {app: string, window: string} window 8 | */ 9 | 10 | /** 11 | * Get the active window 12 | * @param {getActiveWindowCallback} callback - The callback that handles the response. 13 | * @param {integer} [repeats = 1] - Number of repeats; Use -1 to infinity repeats 14 | * @param {float} [interval = 0] - Loop interval in seconds. For milliseconds use fraction (0.1 = 100ms) 15 | */ 16 | exports.getActiveWindow = function(callback,repeats,interval){ 17 | const spawn = require('child_process').spawn; 18 | 19 | interval = (interval) ? interval : 0; 20 | repeats = (repeats) ? repeats : 1; 21 | 22 | //Scape negative number of repeats on Windows OS 23 | if (process.platform == 'win32' && repeats < 0 ){ 24 | repeats = '\\-1'; 25 | } 26 | 27 | parameters = config.parameters; 28 | parameters.push(repeats); 29 | parameters.push(process.platform == 'win32' ? (interval * 1000 | 0) : interval); 30 | 31 | //Run shell script 32 | const ls = spawn(config.bin,parameters); 33 | ls.stdout.setEncoding('utf8'); 34 | 35 | //Obtain successful response from script 36 | ls.stdout.on('data', function(stdout){ 37 | callback(reponseTreatment(stdout.toString())); 38 | }); 39 | 40 | //Obtain error response from script 41 | ls.stderr.on("data",function(stderr){ 42 | throw stderr.toString(); 43 | }); 44 | 45 | ls.stdin.end(); 46 | } 47 | 48 | /** 49 | * Treat and format the response string and put it into a object 50 | * @function reponseTreatment 51 | * @param {string} String received from script 52 | */ 53 | function reponseTreatment(response){ 54 | window = {}; 55 | if(process.platform == 'linux'){ 56 | response = response.replace(/(WM_CLASS|WM_NAME)(\(\w+\)\s=\s)/g,'').split("\n",2); 57 | window.app = response[0]; 58 | window.title = response[1]; 59 | }else if (process.platform == 'win32'){ 60 | response = response.replace(/(@{ProcessName=| AppTitle=)/g,'').slice(0,-1).split(';',2); 61 | window.app = response[0]; 62 | window.title = response[1]; 63 | }else if(process.platform == 'darwin'){ 64 | response = response.split(","); 65 | window.app = response[0]; 66 | window.title = response[1].replace(/\n$/, "").replace(/^\s/, ""); 67 | } 68 | return window; 69 | } 70 | 71 | /** 72 | * Get script config accordingly the operating system 73 | * @function getConfig 74 | */ 75 | function getConfig(){ 76 | //Retrieve configs 77 | var configs = JSON.parse(fs.readFileSync(__dirname+'/configs.json', 'utf8')); 78 | var path = require("path"); 79 | 80 | switch(process.platform){ 81 | case 'linux': 82 | case 'linux2': 83 | config = configs.linux 84 | break; 85 | case 'win32': 86 | config = configs.win32 87 | break; 88 | case 'darwin': 89 | config = configs.mac; 90 | break; 91 | default: 92 | throw "Operating System not supported yet. "+process.platform; 93 | } 94 | //Append directory to script url 95 | script_url = path.join(__dirname,config.script_url); 96 | config.parameters.push(script_url); 97 | 98 | //Append directory to subscript url on OSX 99 | if(process.platform=="darwin"){ 100 | config.parameters.push(path.join(__dirname,config.subscript_url)); 101 | } 102 | 103 | return config; 104 | } 105 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "active-window", 3 | "version": "0.1.0", 4 | "description": "Get active window title.", 5 | "main": "index.js", 6 | "contributors":[{ "name" : "Jason Stallings " 7 | , "email" : "jason@stallin.gs" 8 | , "url" : ""}, 9 | { "name" : "Robson Vieira" 10 | , "email" : "robsonvnasc@gmail.com" 11 | , "url" : ""} 12 | ], 13 | "license": "MIT", 14 | "dependencies": {} 15 | } 16 | -------------------------------------------------------------------------------- /scripts/linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | n=$1 3 | while [ 0 != $n ] 4 | do 5 | xprop -id $(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2) WM_CLASS WM_NAME 6 | sleep $2 7 | if [ "$n" -gt "0" ] 8 | then 9 | n=`expr $n - 1` 10 | fi 11 | done 12 | -------------------------------------------------------------------------------- /scripts/mac.scpt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env osascript 2 | global frontApp, frontAppName, windowTitle 3 | set windowTitle to "" 4 | tell application "System Events" 5 | set frontApp to first application process whose frontmost is true 6 | set frontAppName to name of frontApp 7 | tell process frontAppName 8 | tell (1st window whose value of attribute "AXMain" is true) 9 | set windowTitle to value of attribute "AXTitle" 10 | end tell 11 | end tell 12 | end tell 13 | return {frontAppName,windowTitle} 14 | -------------------------------------------------------------------------------- /scripts/mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Using bash script to run osascript because applescript do not print to stdout 3 | x=$2 4 | while(($x != "0" )) 5 | do 6 | osascript $1 7 | if [ "$x" -gt "0" ] 8 | then 9 | ((x-=1)) 10 | fi 11 | sleep $3 12 | done 13 | -------------------------------------------------------------------------------- /scripts/windows.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [string]$n,[string]$interval 4 | ) 5 | Add-Type @" 6 | using System; 7 | using System.Runtime.InteropServices; 8 | public class UserWindows { 9 | [DllImport("user32.dll")] 10 | public static extern IntPtr GetForegroundWindow(); 11 | } 12 | "@ 13 | try { 14 | while($n -ne 0){ 15 | $ActiveHandle = [UserWindows]::GetForegroundWindow() 16 | $Process = Get-Process | ? {$_.MainWindowHandle -eq $activeHandle} 17 | $string = $Process | Select ProcessName, @{Name="AppTitle";Expression= {($_.MainWindowTitle)}} 18 | Write-Host -NoNewline $string 19 | Start-Sleep -m $interval 20 | If ($n -gt 0) {$n-=1} 21 | } 22 | } catch { 23 | Write-Error "Failed to get active Window details. More Info: $_" 24 | } 25 | --------------------------------------------------------------------------------