Also in windows you can easy export the X11 sessions of a remote ssh session, for who doesn’t konow how to do it in linux here is it: is very easy, just type ssh -X (or -Y in some ssh versions).
From windows is pretty easy too: you need just an ssh client like putty and an X11 server, like Xming.
For example let’s try to launch baobab, a disk usage analyzer GUI very useful to find files and directory that are wasting space on our linux machine:
in a normal putty ssh session we get:
dev:~# baobab
(baobab:19029): Gtk-WARNING **: cannot open display:
Sometimes in javascript you feel the need to control function calls for limiting the number of consequential calls, for example, imagine to have a search box that fetches live database data like this:
<label for="livesearch"> Search globally in last published tweets:</label> <input id="livesearch" type="text" onKeyUp="doDBSearch(this.value)"/>
function doDBSearch(txt){
if (txt.length>3){
Ajax.searchInLastPublicTweets(txt,callback);
}
}
Wow! here we have an awesome 2.0 live search box (like the facebook friend search one, or better, because here we have also a live, non-cacheable, backend: a server database with user last messages, messages that needs to be always updated, that are not chaceable in a javascript store to get easly and quickly accessible data for the onKeyUp event, facebook friendships are semi-static data, yes friendships can be considered static data in a one-page context, live logs not! they need to be always updated, they need a server backend.
So what’s the problem in us awesome live searchbox?
When type quickly in the searchbox how many ajax call it will do?
Enough to get the user browser stalled (and the user out of our site).
i need to prevent this (also for server benefit) and to attach the ajax call to an dreamable DOM event like onQuicklyKeyPressSetFinished.
but i’m sorry, this event doesn’t exists like it doesn’t exists yetthe possibility to do onUserTought=”codeItForMe(event.needs);”.…
so here it is the solution:
var rateLimitTimer=new Array();
function jsExecRateLimitFilterWithArguments(ms,fname,fn){
var args = Array.prototype.slice.call(arguments);
rateLimitTimer[fname] && clearTimeout(rateLimitTimer[fname]);
rateLimitTimer[fname] = setTimeout(function(){
fn.apply(args.slice(4,args.length)); //call the function with the remaning extra arguments
rateLimitTimer[fname] = null;
}, ms);
}
Sometimes you need to be alerted when some event or action happens, but the event or action could happen multiple times in quick succession. A perfect example of this is window.onscroll. The window.onscroll event fires entirely too much. Not only that, it fires inconsistently across browsers. This has been talked about before. Here, I offer a solution:
We can make perfect use of some JavaScript built-ins: setTimeout and clearTimeout, and some uber-cool Dojo magic: dojo.publish and dojo.subscribe. PubSub is a mechanism for arbitrary communication between elements. The usage pattern fits here perfectly. Because window.onscroll fires so much, having multiple connections to this event can cause serious slowdowns in your application when the user scrolls. This technique involves connecting to window.onscroll once, and rate-limiting the firing of this event to something more manageable.
Start by making the connection. We’ll wrap it in an anonymous-self-executing function to scope our variables and keep them out of the global space:
(function(d){
var timer, // create a variable to store a timeout
rate = 50 //ms .. and a variable to use for the delay
;
// setup one connection
d.connect(d.global, "onscroll", function(e){
// if this function has been previously called and not fired,
// clear the timeout
timer && clearTimeout(timer);
timer = setTimeout(function(){
// publish a custom topic when this timeout executes
d.publish("/window/scrolled", [e]);
timer = null;
}, rate);
});
})(dojo);
If the onscroll event fires 100 times in a short period, only the last occurrence will fire the publish. We can utilize this rate-limited version of onscroll simply by subscribing to the “/window/scrolled” topic.
dojo.subscribe("/window/scrolled", function(e){
// do some recalculation based on knowing the scrolling is "done".
// will fire at MOST once per 50ms, so won't be very expensive
});
This technique can be applied to most anything. Perhaps you have a button which sends an Ajax request. Some users double and triple-click buttons out of habit, inadequate visual feedback or a number of other reasons. We can ensure that only one click is allowed within a rate limited window. Same basic setup, different event. The original connecting code might look something like this:
(function(d){
// this sends our POST based on whatever form
var someFunction = function(e){
dojo.xhrPost({ form:"someFormId" });
}
// setup the click events.
d.query(".buttons").onclick(someFunction);
})(dojo);
If a user clicks something with class=”buttons” rapidly in succession, `someFunction` will be called that many times, causing
many Ajax requests to be sent. Converting the code to something which will only fire once per `rate` ms is
(function(d){
var someFunction = function(e){
dojo.xhrPost({ form:"someFormId" });
}
var timer, rate = 50;
dojo.query(".buttons").onclick(function(e){
timer && clearTimeout(timer);
timer = setTimeout(function(){
someFunction({ target: e.target });
timer = null;
}, rate);
});
})(dojo);
Getting a little more advanced, we can take this concept and reduce it to a common function. We’ll invent a new API to handle all the rate-limiting locally. We’ll just make a function which accepts an extra parameter for the rate to set:
(function(d, nl){
d.connectLimited = function(rate, target, event, scope, cb, fixDom){
// summary: Just like `dojo.connect`, but takes an additional argument BEFORE
// standard connect() arguments: rate. This value is used to prevent
// rapid successive calls to this event
var timer,
fn = scope && cb ? d.hitch(scope, cb) : scope
;
return d.connect(target, event, function(e){
timer && clearTimeout(timer);
var args = arguments;
timer = setTimeout(function(){
fn.apply(d, args);
timer = null;
}, rate);
}, null, fixDom);
}
nl.prototype.connectLimited = function(rate, event, scope, cb, fixDom){
// not a straight forEach, need to shift `node` into each call
return this.forEach(function(node){
d.connectLimited.call(d, rate, node, event, scope, cb, fixDom);
});
}
})(dojo, dojo.NodeList);
By returning the handle from the rate-limited dojo.connect call, we are able to disconnect this event with dojo.disconnect.
Now, to use it we simply call the function passing a rate in addition to whatever we normally would have called: