diff --git a/chrome.proto b/chrome.proto index 42ecc90..586cbef 100644 --- a/chrome.proto +++ b/chrome.proto @@ -6,8 +6,20 @@ package trackd; service Chrome { rpc session_changed(SessionChangedRequest) returns (google.protobuf.Empty); + + rpc set_session_for_window_id(SetSessionForWindowIdRequest) returns (google.protobuf.Empty); + rpc set_active_window(SetActiveWindowRequest) returns (google.protobuf.Empty); } message SessionChangedRequest { string session_name = 1; } + +message SetSessionForWindowIdRequest { + string session_name = 1; + int64 window_id = 2; +} + +message SetActiveWindowRequest { + int64 window_id = 3; +} diff --git a/chrome_extension/client_chrome.js b/chrome_extension/client_chrome.js index ba0264b..51db998 100644 --- a/chrome_extension/client_chrome.js +++ b/chrome_extension/client_chrome.js @@ -4,6 +4,44 @@ chrome.runtime.onInstalled.addListener(function() { const {SessionChangedRequest} = require('./chrome_pb.js'); const {ChromeClient} = require('./chrome_grpc_web_pb.js'); + function onFocusChanged(windowId) { + console.log(`${windowId} is focused`); + + let groupId = windowToSessionMap.get(windowId); + chrome.tabGroups.get(groupId, group => { + console.log(`groupId: ${groupId}, group: ${group}`); + }); + } + + chrome.windows.onFocusChanged.addListener(onFocusChanged); + + let windowToSessionMap = new Map(); + windowToSessionMap.set(-1, -1); + + chrome.windows.getAll({populate: true}, windows => { + console.log(windows); + + windowToSessionMap.clear(); + + for (let window_ of windows) { + for (let tab of window_.tabs) { + if (tab.groupId != -1) { + windowToSessionMap.set(window_.id, tab.groupId); + break; + } + } + windowToSessionMap.set(window_.id, -2); + } + + // The assumption is that as we just started, the Chrome should still be focused. + // It may be good to check in trackd though that Chrome's XWindow is indeed focused + // when this plugin reports so. + windows.getLastFocused({}, window_ => { + onFocusChanged(window_.id); + }); + }); + + let client = new ChromeClient('http://localhost:3142', null, null); let request = new SessionChangedRequest(); diff --git a/chrome_extension/main.js b/chrome_extension/main.js index 4e69cbf..6a9485e 100644 --- a/chrome_extension/main.js +++ b/chrome_extension/main.js @@ -1 +1 @@ -(()=>{var __webpack_modules__={597:(e,t,o)=>{const r={};r.web=o(758);var n=o(607);const s={};s.trackd=o(250),s.trackd.ChromeClient=function(e,t,o){o||(o={}),o.format="binary",this.client_=new r.web.GrpcWebClientBase(o),this.hostname_=e},s.trackd.ChromePromiseClient=function(e,t,o){o||(o={}),o.format="binary",this.client_=new r.web.GrpcWebClientBase(o),this.hostname_=e};const i=new r.web.MethodDescriptor("/trackd.Chrome/session_changed",r.web.MethodType.UNARY,s.trackd.SessionChangedRequest,n.Empty,(function(e){return e.serializeBinary()}),n.Empty.deserializeBinary);new r.web.AbstractClientBase.MethodInfo(n.Empty,(function(e){return e.serializeBinary()}),n.Empty.deserializeBinary),s.trackd.ChromeClient.prototype.session_changed=function(e,t,o){return this.client_.rpcCall(this.hostname_+"/trackd.Chrome/session_changed",e,t||{},i,o)},s.trackd.ChromePromiseClient.prototype.session_changed=function(e,t){return this.client_.unaryCall(this.hostname_+"/trackd.Chrome/session_changed",e,t||{},i)},e.exports=s.trackd},250:(e,t,o)=>{var r=o(260),n=r,s=Function("return this")(),i=o(607);n.object.extend(proto,i),n.exportSymbol("proto.trackd.SessionChangedRequest",null,s),proto.trackd.SessionChangedRequest=function(e){r.Message.initialize(this,e,0,-1,null,null)},n.inherits(proto.trackd.SessionChangedRequest,r.Message),n.DEBUG&&!COMPILED&&(proto.trackd.SessionChangedRequest.displayName="proto.trackd.SessionChangedRequest"),r.Message.GENERATE_TO_OBJECT&&(proto.trackd.SessionChangedRequest.prototype.toObject=function(e){return proto.trackd.SessionChangedRequest.toObject(e,this)},proto.trackd.SessionChangedRequest.toObject=function(e,t){var o={sessionName:r.Message.getFieldWithDefault(t,1,"")};return e&&(o.$jspbMessageInstance=t),o}),proto.trackd.SessionChangedRequest.deserializeBinary=function(e){var t=new r.BinaryReader(e),o=new proto.trackd.SessionChangedRequest;return proto.trackd.SessionChangedRequest.deserializeBinaryFromReader(o,t)},proto.trackd.SessionChangedRequest.deserializeBinaryFromReader=function(e,t){for(;t.nextField()&&!t.isEndGroup();)switch(t.getFieldNumber()){case 1:var o=t.readString();e.setSessionName(o);break;default:t.skipField()}return e},proto.trackd.SessionChangedRequest.prototype.serializeBinary=function(){var e=new r.BinaryWriter;return proto.trackd.SessionChangedRequest.serializeBinaryToWriter(this,e),e.getResultBuffer()},proto.trackd.SessionChangedRequest.serializeBinaryToWriter=function(e,t){var o;(o=e.getSessionName()).length>0&&t.writeString(1,o)},proto.trackd.SessionChangedRequest.prototype.getSessionName=function(){return r.Message.getFieldWithDefault(this,1,"")},proto.trackd.SessionChangedRequest.prototype.setSessionName=function(e){return r.Message.setProto3StringField(this,1,e)},n.object.extend(t,proto.trackd)},260:function(__unused_webpack_module,exports,__webpack_require__){var $jscomp=$jscomp||{};$jscomp.scope={},$jscomp.findInternal=function(e,t,o){e instanceof String&&(e=String(e));for(var r=e.length,n=0;n=r}}),"es6","es3"),$jscomp.polyfill("Array.prototype.find",(function(e){return e||function(e,t){return $jscomp.findInternal(this,e,t).v}}),"es6","es3"),$jscomp.polyfill("String.prototype.startsWith",(function(e){return e||function(e,t){var o=$jscomp.checkStringArgs(this,e,"startsWith");e+="";var r=o.length,n=e.length;t=Math.max(0,Math.min(0|t,o.length));for(var s=0;s=n}}),"es6","es3"),$jscomp.polyfill("String.prototype.repeat",(function(e){return e||function(e){var t=$jscomp.checkStringArgs(this,null,"repeat");if(0>e||1342177279>>=1)&&(t+=t);return o}}),"es6","es3");var COMPILED=!0,goog=goog||{};goog.global=this||self,goog.isDef=function(e){return void 0!==e},goog.isString=function(e){return"string"==typeof e},goog.isBoolean=function(e){return"boolean"==typeof e},goog.isNumber=function(e){return"number"==typeof e},goog.exportPath_=function(e,t,o){e=e.split("."),o=o||goog.global,e[0]in o||void 0===o.execScript||o.execScript("var "+e[0]);for(var r;e.length&&(r=e.shift());)!e.length&&goog.isDef(t)?o[r]=t:o=o[r]&&o[r]!==Object.prototype[r]?o[r]:o[r]={}},goog.define=function(e,t){if(!COMPILED){var o=goog.global.CLOSURE_UNCOMPILED_DEFINES,r=goog.global.CLOSURE_DEFINES;o&&void 0===o.nodeType&&Object.prototype.hasOwnProperty.call(o,e)?t=o[e]:r&&void 0===r.nodeType&&Object.prototype.hasOwnProperty.call(r,e)&&(t=r[e])}return t},goog.FEATURESET_YEAR=2012,goog.DEBUG=!0,goog.LOCALE="en",goog.TRUSTED_SITE=!0,goog.STRICT_MODE_COMPATIBLE=!1,goog.DISALLOW_TEST_ONLY_CODE=COMPILED&&!goog.DEBUG,goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING=!1,goog.provide=function(e){if(goog.isInModuleLoader_())throw Error("goog.provide cannot be used within a module.");if(!COMPILED&&goog.isProvided_(e))throw Error('Namespace "'+e+'" already declared.');goog.constructNamespace_(e)},goog.constructNamespace_=function(e,t){if(!COMPILED){delete goog.implicitNamespaces_[e];for(var o=e;(o=o.substring(0,o.lastIndexOf(".")))&&!goog.getObjectByName(o);)goog.implicitNamespaces_[o]=!0}goog.exportPath_(e,t)},goog.getScriptNonce=function(e){return e&&e!=goog.global?goog.getScriptNonce_(e.document):(null===goog.cspNonce_&&(goog.cspNonce_=goog.getScriptNonce_(goog.global.document)),goog.cspNonce_)},goog.NONCE_PATTERN_=/^[\w+/_-]+[=]{0,2}$/,goog.cspNonce_=null,goog.getScriptNonce_=function(e){return(e=e.querySelector&&e.querySelector("script[nonce]"))&&(e=e.nonce||e.getAttribute("nonce"))&&goog.NONCE_PATTERN_.test(e)?e:""},goog.VALID_MODULE_RE_=/^[a-zA-Z_$][a-zA-Z0-9._$]*$/,goog.module=function(e){if(!goog.isString(e)||!e||-1==e.search(goog.VALID_MODULE_RE_))throw Error("Invalid module identifier");if(!goog.isInGoogModuleLoader_())throw Error("Module "+e+" has been loaded incorrectly. Note, modules cannot be loaded as normal scripts. They require some kind of pre-processing step. You're likely trying to load a module via a script tag or as a part of a concatenated bundle without rewriting the module. For more info see: https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.");if(goog.moduleLoaderState_.moduleName)throw Error("goog.module may only be called once per module.");if(goog.moduleLoaderState_.moduleName=e,!COMPILED){if(goog.isProvided_(e))throw Error('Namespace "'+e+'" already declared.');delete goog.implicitNamespaces_[e]}},goog.module.get=function(e){return goog.module.getInternal_(e)},goog.module.getInternal_=function(e){if(!COMPILED){if(e in goog.loadedModules_)return goog.loadedModules_[e].exports;if(!goog.implicitNamespaces_[e])return null!=(e=goog.getObjectByName(e))?e:null}return null},goog.ModuleType={ES6:"es6",GOOG:"goog"},goog.moduleLoaderState_=null,goog.isInModuleLoader_=function(){return goog.isInGoogModuleLoader_()||goog.isInEs6ModuleLoader_()},goog.isInGoogModuleLoader_=function(){return!!goog.moduleLoaderState_&&goog.moduleLoaderState_.type==goog.ModuleType.GOOG},goog.isInEs6ModuleLoader_=function(){if(goog.moduleLoaderState_&&goog.moduleLoaderState_.type==goog.ModuleType.ES6)return!0;var e=goog.global.$jscomp;return!!e&&"function"==typeof e.getCurrentModulePath&&!!e.getCurrentModulePath()},goog.module.declareLegacyNamespace=function(){if(!COMPILED&&!goog.isInGoogModuleLoader_())throw Error("goog.module.declareLegacyNamespace must be called from within a goog.module");if(!COMPILED&&!goog.moduleLoaderState_.moduleName)throw Error("goog.module must be called prior to goog.module.declareLegacyNamespace.");goog.moduleLoaderState_.declareLegacyNamespace=!0},goog.declareModuleId=function(e){if(!COMPILED){if(!goog.isInEs6ModuleLoader_())throw Error("goog.declareModuleId may only be called from within an ES6 module");if(goog.moduleLoaderState_&&goog.moduleLoaderState_.moduleName)throw Error("goog.declareModuleId may only be called once per module.");if(e in goog.loadedModules_)throw Error('Module with namespace "'+e+'" already exists.')}if(goog.moduleLoaderState_)goog.moduleLoaderState_.moduleName=e;else{var t=goog.global.$jscomp;if(!t||"function"!=typeof t.getCurrentModulePath)throw Error('Module with namespace "'+e+'" has been loaded incorrectly.');t=t.require(t.getCurrentModulePath()),goog.loadedModules_[e]={exports:t,type:goog.ModuleType.ES6,moduleId:e}}},goog.setTestOnly=function(e){if(goog.DISALLOW_TEST_ONLY_CODE)throw e=e||"",Error("Importing test-only code into non-debug environment"+(e?": "+e:"."))},goog.forwardDeclare=function(e){},COMPILED||(goog.isProvided_=function(e){return e in goog.loadedModules_||!goog.implicitNamespaces_[e]&&goog.isDefAndNotNull(goog.getObjectByName(e))},goog.implicitNamespaces_={"goog.module":!0}),goog.getObjectByName=function(e,t){e=e.split("."),t=t||goog.global;for(var o=0;o>>0),goog.uidCounter_=0,goog.getHashCode=goog.getUid,goog.removeHashCode=goog.removeUid,goog.cloneObject=function(e){var t=goog.typeOf(e);if("object"==t||"array"==t){if("function"==typeof e.clone)return e.clone();for(var o in t="array"==t?[]:{},e)t[o]=goog.cloneObject(e[o]);return t}return e},goog.bindNative_=function(e,t,o){return e.call.apply(e.bind,arguments)},goog.bindJs_=function(e,t,o){if(!e)throw Error();if(2{"use strict";class X{constructor(){if(new.target!=String)throw 1;this.x=42}}let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof String))throw 1;for(const a of[2,3]){if(a==2)continue;function f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()==3}})()')})),a("es7",(function(){return b("2 ** 2 == 4")})),a("es8",(function(){return b("async () => 1, true")})),a("es9",(function(){return b("({...rest} = {}), true")})),a("es_next",(function(){return!1})),{target:c,map:d}},goog.Transpiler.prototype.needsTranspile=function(e,t){if("always"==goog.TRANSPILE)return!0;if("never"==goog.TRANSPILE)return!1;if(!this.requiresTranspilation_){var o=this.createRequiresTranspilation_();this.requiresTranspilation_=o.map,this.transpilationTarget_=this.transpilationTarget_||o.target}if(e in this.requiresTranspilation_)return!!this.requiresTranspilation_[e]||!(!goog.inHtmlDocument_()||"es6"!=t||"noModule"in goog.global.document.createElement("script"));throw Error("Unknown language mode: "+e)},goog.Transpiler.prototype.transpile=function(e,t){return goog.transpile_(e,t,this.transpilationTarget_)},goog.transpiler_=new goog.Transpiler,goog.protectScriptTag_=function(e){return e.replace(/<\/(SCRIPT)/gi,"\\x3c/$1")},goog.DebugLoader_=function(){this.dependencies_={},this.idToPath_={},this.written_={},this.loadingDeps_=[],this.depsToLoad_=[],this.paused_=!1,this.factory_=new goog.DependencyFactory(goog.transpiler_),this.deferredCallbacks_={},this.deferredQueue_=[]},goog.DebugLoader_.prototype.bootstrap=function(e,t){function o(){r&&(goog.global.setTimeout(r,0),r=null)}var r=t;if(e.length){t=[];for(var n=0;n<\/script>",t.write(goog.TRUSTED_TYPES_POLICY_?goog.TRUSTED_TYPES_POLICY_.createHTML(r):r)}else{var n=t.createElement("script");n.defer=goog.Dependency.defer_,n.async=!1,n.type="text/javascript",(r=goog.getScriptNonce())&&n.setAttribute("nonce",r),goog.DebugLoader_.IS_OLD_IE_?(e.pause(),n.onreadystatechange=function(){"loaded"!=n.readyState&&"complete"!=n.readyState||(e.loaded(),e.resume())}):n.onload=function(){n.onload=null,e.loaded()},n.src=goog.TRUSTED_TYPES_POLICY_?goog.TRUSTED_TYPES_POLICY_.createScriptURL(this.path):this.path,t.head.appendChild(n)}}else goog.logToConsole_("Cannot use default debug loader outside of HTML documents."),"deps.js"==this.relativePath?(goog.logToConsole_("Consider setting CLOSURE_IMPORT_SCRIPT before loading base.js, or setting CLOSURE_NO_DEPS to true."),e.loaded()):e.pause()},goog.Es6ModuleDependency=function(e,t,o,r,n){goog.Dependency.call(this,e,t,o,r,n)},goog.inherits(goog.Es6ModuleDependency,goog.Dependency),goog.Es6ModuleDependency.prototype.load=function(e){if(goog.global.CLOSURE_IMPORT_SCRIPT)goog.global.CLOSURE_IMPORT_SCRIPT(this.path)?e.loaded():e.pause();else if(goog.inHtmlDocument_()){var t=goog.global.document,o=this;if(goog.isDocumentLoading_()){var r=function(e,o){e=o?'